C读取由具有无界字大小的空格分隔的文本文件

我有一个文本文件,其中包含由空格分隔的单词(字符串)。 字符串的大小不受限制,字数也不限。 我需要做的是将文件中的所有单词放在列表中。 (假设列表工作正常)。 我无法弄清楚如何克服无限大小的字大小问题。 我试过这个:

FILE* f1; f1 = fopen("file1.txt", "rt"); int a = 1; char c = fgetc(f1); while (c != ' '){ c = fgetc(f1); a = a + 1; } char * word = " "; fgets(word, a, f1); printf("%s", word); fclose(f1); getchar(); 

我的文本文件如下所示:

  this is sparta 

请注意,我能得到的只是第一个单词,即使我做得不正确,因为我得到了错误:

 Access violation writing location 0x00B36860. 

有人可以帮帮我吗?

根据上述评论者的建议,只要没有足够的,或者显然足够的,就会重新分配记忆。

 #include  #include  #include  void fatal(char *msg) { printf("%s\n", msg); exit (1); } int main() { FILE* f1 = NULL; char *word = NULL; size_t size = 2; long fpos = 0; char format [32]; if ((f1 = fopen("file1.txt", "rt")) == NULL) // open file fatal("Failed to open file"); if ((word = malloc(size)) == NULL) // word memory fatal("Failed to allocate memory"); sprintf (format, "%%%us", (unsigned)size-1); // format for fscanf while(fscanf(f1, format, word) == 1) { while (strlen(word) >= size-1) { // is buffer full? size *= 2; // double buff size printf ("** doubling to %u **\n", (unsigned)size); if ((word = realloc(word, size)) == NULL) fatal("Failed to reallocate memory"); sprintf (format, "%%%us", (unsigned)size-1);// new format spec fseek(f1, fpos, SEEK_SET); // re-read the line if (fscanf(f1, format, word) == 0) fatal("Failed to re-read file"); } printf ("%s\n", word); fpos = ftell(f1); // mark file pos } free(word); fclose(f1); return(0); } 

节目输入

 this is sparta help 30000000000000000000000000000000000000000 me 

节目输出:

 ** doubling to 4 ** ** doubling to 8 ** this is sparta help ** doubling to 16 ** ** doubling to 32 ** ** doubling to 64 ** 30000000000000000000000000000000000000000 me 

你在哪个平台?

如果你正在使用POSIX-ish平台,那么考虑使用getline()读取无限大小的行,然后使用strcspn()strpbrk()strtok_r()或(如果你真的决定使用你的代码)不可重复使用) strtok()获取单词的边界,最后使用strdup()创建单词的副本。 strdup()返回的指针将存储在通过realloc()管理的char *数组中。

如果你没有足够的POSIX-ish平台,那么你需要使用fgets()检查你是否真的读了整行 – 如果你的初始行不是,那么使用realloc()来分配更多空间够长了。 一旦你有了一条线,你可以像以前一样拆分它。

你可以搞乱POSIX getdelim()除了它只需要一个分隔符,你可能想要空格和换行符来标记单词的结尾(也可能是标签),它将无法处理。

而且,如果你使用的是足够现代的POSIX系统,你可以考虑使用m修饰符来scanf()

 char *word = 0; while (scanf("%ms", &word) == 1) …store word in your list… 

当它可用时,这甚至更简单。