我想用给定的分隔符分割单词的字符串(行)。我在下面写了这段代码:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
unsigned int countWords(char *stringLine)
{
unsigned int count = 0;
char* tmp = stringLine;
char* last = 0;
const char delim = '/';
while (*tmp)
{
if (delim == *tmp)
{
count++;
last = tmp;
}
tmp++;
}
return count-1;
}
char **getWordsFromString(char *stringLine)
{
char** sizeNames = 0;
unsigned int count = 0;
const char *delim = "/";
count = countWords(stringLine);
sizeNames = malloc(sizeof(char*) * count);
if(sizeNames == NULL)
{
return NULL;
}
if (sizeNames)
{
size_t idx = 0;
char* token = strtok(stringLine, delim);
while (token)
{
if(idx < count)
{
exit(-1);
}
*(sizeNames + idx++) = strdup(token);
token = strtok(0, delim);
}
if(idx == count - 1)
{
exit(-1);
}
*(sizeNames + idx) = 0;
}
return sizeNames;
}
void showWords(char *stringLine)
{
unsigned int size = countWords(stringLine), i = 0;
char** sizeNames = getWordsFromString(stringLine);
for(i=0; i<size; i++)
{
printf("%s\n", sizeNames[i]);
}
}
int main()
{
char words[] = "hello/world/!/its/me";
int c = countWords(words);
printf("c = %d\n", c);
showWords(words);
return 0;
}
问题是我的代码无法正常工作。它在字符串中显示了适当数量的单词但不拆分它们,只给出了255个返回码。我该如何改进呢?
答案 0 :(得分:2)
这里:
size_t idx = 0;
char* token = strtok(stringLine, delim);
while (token)
{
if(idx < count)
{
exit(-1);
}
鉴于您将idx
设置为0
,只要count
大于零,您就会始终exit()
。可能你想要一个不同的if
条件。您的系统上的退出代码可能未签名,因此-1
才会转换为255
。
答案 1 :(得分:1)
我个人更喜欢用strtok使用for循环表示法......我会像这样编写核心循环:
if (sizeNames)
{
size_t idx = 0;
char *token;
for( token = strtok(stringLine, delim);
token && idx<count;
token = strtok(NULL, delim), idx++)
{
*(sizeNames + idx) = strdup(token);
}
*(sizeNames + idx) = NULL;
}
但是,由于你在最后一个单词之后是NULL终止,所以请确保在下面使用count + 1,否则上面的行*(sizeNames + idx) = NULL;
可能会出现段错误:
sizeNames = malloc(sizeof(char*) * (count+1));
PS ...你的countWords例程也会返回错误的答案。可能想要替换:
return count-1;
使用:
if( (last+1)==tmp )
return count;
return count+1;
此外,使用strdup()
分配的内存永远不会在任何地方释放,因此如果通过valgrind运行,则会出现泄漏错误。
注意,您不必使用strdup()
,因为strtok()
会将NUL留在源字符串中找到分隔符的位置,因此您可以写一下:
*(sizeNames + idx) = token;
位于for循环的核心。由于这种破坏性行为,strtok()
有时仅在要分析的缓冲区副本上运行。