fgets不读整行

我有一个简单的函数,它应该从标准输入读取行并将其放入一个char数组中,然后我在循环中调用此函数直到输入EOF。 问题是,对于极长的行(超过10k个字符),fgets只读取多个字符并停止,虽然它没有遇到任何\ n且缓冲区有足够的空间,因此下一次调用此函数会读取其余的这条线。 有这种行为的原因(错误编写的代码,我不知道的一些缓冲区)? 有可能解决它吗? 如果我在代码中出错了,如果你指出它,我将不胜感激。

static int getLine(char** line){ if(feof(stdin)) return 0; int len=0; char* pointer=NULL; int max = 1; while(1){ max+=400; *line=(char*)realloc( *line,max); if(pointer==NULL) pointer=*line; if(fgets(pointer, 401, stdin)==NULL)break; int len1=strlen(pointer); len+=len1; if(len1!=400 || pointer[len1]=='\n')break; pointer+=len1; } if(len==0)return 0; if((*line)[len-1]=='\n'){ *line=(char*)realloc(*line, len); (*line)[len-1]='\0'; return len-1;}//without \n return len; } 

我认为您的问题很可能是您使用pointer的方式:

 char* pointer=NULL; int max = 1; while(1){ max+=400; *line=(char*)realloc( *line,max); if(pointer==NULL) pointer=*line; if(fgets(pointer, 401, stdin)==NULL) break; int len1=strlen(pointer); len+=len1; if(len1!=400 || pointer[len1]=='\n') break; pointer+=len1; } 

麻烦的是realloc()可以改变数据存储的位置,但是你将它固定到你第一次给出的位置。 如果处理大量数据,则更有可能在重新分配时移动数据。 您可以通过跟踪*line的值来诊断它realloc()在每次迭代时在realloc()之后打印它)。

修复非常简单:使用偏移量而不是指针作为权威长度,并在每次迭代时设置pointer

 enum { EXTRA_LEN = 400 }; size_t offset = 0; int max = 1; while (1) { max += EXTRA_LEN; char *space = (char*)realloc(*line, max); // Leak prevention if (space == 0) return len; *line = space; char *pointer = *line + offset; if (fgets(pointer, EXTRA_LEN + 1, stdin) == NULL) break; int len1 = strlen(pointer); len += len1; if (len1 != EXTRA_LEN || pointer[len1] == '\n') break; offset += len1; } 

我对fgets()调用中使用401而不是400有所保留,但我没有精力去确定它是否正确。 我已尽力完成对代码的最小更改; 如果是我正在抛光的代码,我可能会进行更广泛的更改。 (特别是, max将从0开始,而不是1,并且我不会在调用fgets()使用+1。