原始答案
一个问题是您缺少else
for 子句if (*string)
,该子句需要将字符设置为空白。另一个问题是你读到了字符串的末尾。
char *getWord(const char *string)
{
char *chars = "-_";
int max = 10;
int len;
char *res = malloc(max + 1);
if (res == 0)
return res;
for (len = 0; len < max; len++)
{
if (*string)
{
if (!strchr(chars, *string))
res[len] = *string;
else
res[len] = ' ';
string++;
}
else
res[len] = ' ';
}
res[len] = 0;
return res;
}
这使用常规for (int len = 0; len < max; len++)
循环来逐步遍历分配的数组。代码仅string
在不指向终端空字节时才会增加。每次迭代都有一个赋值res[len]
。该代码还检查内存分配是否成功——这在实际程序中很重要。
修改后的答案
该功能getWord2()
可以满足您的要求。注意测试工具。
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
static
char *getWord1(const char *string)
{
char *chars = "-_";
int max = 10;
int len;
char *res = malloc(max + 1);
if (res == 0)
return res;
for (len = 0; len < max; len++)
{
if (*string)
{
if (!strchr(chars, *string))
res[len] = *string;
else
res[len] = ' ';
string++;
}
else
res[len] = ' ';
}
res[len] = 0;
return res;
}
static
char *getWord2(const char *string)
{
char *chars = "-_";
int max = 10;
int len = 0;
char *res = malloc(max + 1);
if (res == 0)
return res;
while (len < max)
{
if (*string)
{
if (!strchr(chars, *string))
res[len++] = *string;
string++;
}
else
res[len++] = ' ';
}
res[len] = 0;
return res;
}
int main(void)
{
const char *data[] =
{
"my-str_a",
"--m--__",
"my str a",
"AbyssinianElephant",
"--m--__m--m--m-m-m-m-m-m-m-m-m-m",
};
for (size_t i = 0; i < sizeof(data)/sizeof(data[0]); i++)
{
char *res1 = getWord1(data[i]);
char *res2 = getWord2(data[i]);
char source[30];
snprintf(source, sizeof(source), "<<%.25s>>", data[i]);
assert(res1 != 0 && res2 != 0); // Reprehensible!
printf("%-30.30s --> <<%s>> or <<%s>>\n", source, res1, res2);
free(res1);
free(res2);
}
return 0;
}
样本输出:
<<my-str_a>> --> <<my str a >> or <<mystra >>
<<--m--__>> --> << m >> or <<m >>
<<my str a>> --> <<my str a >> or <<my str a >>
<<AbyssinianElephant>> --> <<Abyssinian>> or <<Abyssinian>>
<<--m--__m--m--m-m-m-m-m-m->> --> << m m >> or <<mmmmmmmmmm>>
如果 'mmmmmmmmmm' 输出不是您想要的,规范需要收紧一点。调整可能并不难,但确实需要指定。