C在每个空白处分割string

我想用C语言编写一个程序,用单独的一行显示整个句子的每个单词(作为input)。 这是我迄今为止所做的:


void manipulate(char *buffer); int get_words(char *buffer); int main(){ char buff[100]; printf("sizeof %d\nstrlen %d\n", sizeof(buff), strlen(buff)); // Debugging reasons bzero(buff, sizeof(buff)); printf("Give me the text:\n"); fgets(buff, sizeof(buff), stdin); manipulate(buff); return 0; } int get_words(char *buffer){ // Function that gets the word count, by counting the spaces. int count; int wordcount = 0; char ch; for (count = 0; count < strlen(buffer); count ++){ ch = buffer[count]; if((isblank(ch)) || (buffer[count] == '\0')){ // if the character is blank, or null byte add 1 to the wordcounter wordcount += 1; } } printf("%d\n\n", wordcount); return wordcount; } void manipulate(char *buffer){ int words = get_words(buffer); char *newbuff[words]; char *ptr; int count = 0; int count2 = 0; char ch = '\n'; ptr = buffer; bzero(newbuff, sizeof(newbuff)); for (count = 0; count < 100; count ++){ ch = buffer[count]; if (isblank(ch) || buffer[count] == '\0'){ buffer[count] = '\0'; if((newbuff[count2] = (char *)malloc(strlen(buffer))) == NULL) { printf("MALLOC ERROR!\n"); exit(-1); } strcpy(newbuff[count2], ptr); printf("\n%s\n",newbuff[count2]); ptr = &buffer[count + 1]; count2 ++; } } } 

尽pipe输出结果是我想要的,但是在显示最后一个单词之后,我确实有很多黑色空格,而malloc()返回NULL,所以MALLOC错误! 显示在最后。 我可以理解,在我的malloc()实现有一个错误,但我不知道它是什么。

还有更优雅的 – 通常更好的方法来做到这一点?

提前致谢。

http://www.cplusplus.com/reference/clibrary/cstring/strtok/

看看这个,并使用空格字符作为分隔符。 如果你需要更多的提示,请告诉我。

从网站:

 char * strtok ( char * str, const char * delimiters ); 

在第一次调用时,函数需要一个Cstring作为str的参数,其第一个字符被用作扫描令牌的起始位置。 在随后的调用中,函数需要一个空指针,并将最后一个标记结束后的位置作为新的扫描起始位置。

一旦在strtok的调用中发现了str的终止空字符,所有后续对此函数的调用(以空指针作为第一个参数)将返回一个空指针。

参数

  • 海峡
    • Cstring截断。
    • 请注意,该string被分解为更小的string(标记)。 另外[原文如此],可以指定一个空指针,在这种情况下,该函数继续扫描上一次成功调用该函数的地方。
  • 分隔符
    • 包含分隔符的Cstring。
    • 这些可能会因呼叫而异。

返回值

指向在string中find的最后一个标记的指针。 如果没有令牌可供检索,则返回空指针。

 /* strtok example */ #include <stdio.h> #include <string.h> int main () { char str[] ="- This, a sample string."; char * pch; printf ("Splitting string \"%s\" into tokens:\n",str); pch = strtok (str," ,.-"); while (pch != NULL) { printf ("%s\n",pch); pch = strtok (NULL, " ,.-"); } return 0; } 

为了它的乐趣这里是一个基于callback方法的实现:

 const char* find(const char* s, const char* e, int (*pred)(char)) { while( s != e && !pred(*s) ) ++s; return s; } void split_on_ws(const char* s, const char* e, void (*callback)(const char*, const char*)) { const char* p = s; while( s != e ) { s = find(s, e, isspace); callback(p, s); p = s = find(s, e, isnotspace); } } void handle_word(const char* s, const char* e) { // handle the word that starts at s and ends at e } int main() { split_on_ws(some_str, some_str + strlen(some_str), handle_word); } 

malloc(0)可能(可选)返回NULL ,具体取决于实现。 你知道你为什么要调用malloc(0)吗? 或者更准确地说,你是否看到你正在阅读和写作超出arrays的大小?

像其他人所说的strtok_r ,考虑使用strtok_r ,或者类似的东西:

 void printWords(const char *string) { // Make a local copy of the string that we can manipulate. char * const copy = strdup(string); char *space = copy; // Find the next space in the string, and replace it with a newline. while (space = strchr(space,' ')) *space = '\n'; // There are no more spaces in the string; print out our modified copy. printf("%s\n", copy); // Free our local copy free(copy); } 

出错的是get_words()总是返回一个比实际的字数less,所以最终你试图:

 char *newbuff[words]; /* Words is one less than the actual number, so this is declared to be too small. */ newbuff[count2] = (char *)malloc(strlen(buffer)) 

最终, count2总是比你为newbuff[]声明的元素的数量多一个。 为什么malloc()没有返回一个有效的ptr,但我不知道。

你应该是malloc'ing strlen(ptr),而不是strlen(buf)。 另外,你的count2应该限制在单词的数量上。 当你到达你的string的末尾,你继续在缓冲区中的零,并添加零大小的string到你的数组。

就像C中不同风格的string操作一样,下面是一个不修改源string的例子,不使用malloc 。 要find空格我使用libc函数strpbrk

 int print_words(const char *string, FILE *f) { static const char space_characters[] = " \t"; const char *next_space; // Find the next space in the string // while ((next_space = strpbrk(string, space_characters))) { const char *p; // If there are non-space characters between what we found // and what we started from, print them. // if (next_space != string) { for (p=string; p<next_space; p++) { if(fputc(*p, f) == EOF) { return -1; } } // Print a newline // if (fputc('\n', f) == EOF) { return -1; } } // Advance next_space until we hit a non-space character // while (*next_space && strchr(space_characters, *next_space)) { next_space++; } // Advance the string // string = next_space; } // Handle the case where there are no spaces left in the string // if (*string) { if (fprintf(f, "%s\n", string) < 0) { return -1; } } return 0; } 
 char arr[50]; gets(arr); int c=0,i,l; l=strlen(arr); for(i=0;i<l;i++){ if(arr[i]==32){ printf("\n"); } else printf("%c",arr[i]); }