C 读取未知行长度的文件时确定EOF
我有上面的代码片段来读取长度未知的行。我能够像预期的那样从stdin读取单行输入,但是在读取文件时,我在确定文件的EOF时遇到了麻烦 在读取文件时,我在循环中逐行读取它,现在我想在读取所有行后中断循环,但我无法确定何时执行,因此循环将永远执行。请帮我确定断裂条件C 读取未知行长度的文件时确定EOF,c,file,file-io,io,C,File,File Io,Io,我有上面的代码片段来读取长度未知的行。我能够像预期的那样从stdin读取单行输入,但是在读取文件时,我在确定文件的EOF时遇到了麻烦 在读取文件时,我在循环中逐行读取它,现在我想在读取所有行后中断循环,但我无法确定何时执行,因此循环将永远执行。请帮我确定断裂条件 /* Utility function to read lines of unknown lengths */ char *readline(FILE* fp, int max_length) { //The size is e
/* Utility function to read lines of unknown lengths */
char *readline(FILE* fp, int max_length)
{
//The size is extended by the input with the value of the provisional
char *str;
int ch;
int len = 0;
int current_max = max_length;
str = (char*)malloc(sizeof(char)*current_max);
if(!str)
return str;
while((char)(ch = fgetc(fp))!='\n' && ch != EOF)
{
str[len++] = ch;
if(len == current_max)
{
current_max = current_max + max_length;
str = realloc(str, sizeof(char)*current_max);
if(!str)
return str;
}
}
str[len] = '\0';
return str;
}
尝试:
这将EOL处理与EOF处理分开。读取EOF后,对readline的下一次调用将返回一个空字符串,表示已达到EOF。您应该这样更改代码:
while((ch = fgetc(fp))!=EOF)
{
str[len++] = ch;
if (ch=='\n')
break;
}
str[len]= '\0';
return(str);
处理此问题的最佳方法是让
readline
为EOF[或错误]返回NULL。但是,您还必须考虑空行
我已经更改并注释了您的代码,我相信它会起作用。max_length
没有那么有用,因为对realloc
的执行方式进行了更改[请原谅不必要的样式清理]:
char *line;
int eofreached; // pay attention
eofreached = 0;// pay attention
while(eofreached == 0)// pay attention
{
line = readline(fd, MAX_INPUT_LENGTH, &eofreached);// pay attention
/*IF all lines have been read then break off the loop, basically determine EOF ?*
//text processing on the line
}
/* Utility function to read lines of unknown lengths */
char *readline(FILE* fp, int max_length, int* eof_found)// pay attention
{
//The size is extended by the input with the value of the provisional
char *str;
int ch;
int len = 0;
int current_max = max_length;
str = (char*)malloc(sizeof(char)*current_max);
if(!str)
return str;
while((char)(ch = fgetc(fp))!='\n' && ch != EOF)
{
str[len++] = ch;
if(len == current_max)
{
current_max = current_max + max_length;
str = realloc(str, sizeof(char)*current_max);
if(!str)
return str;
}
}
if ( ch == EOF ) // pay attention // this line and next line
*eof_found = 1; // pay attention // can be improved: *eof_found = ch == EOF
str[len] = '\0';
return str;
}
#包括
#包括
#包括
/*用于读取未知长度行的实用函数*/
//返回:字符串指针(NULL表示EOF或realloc失败)
煤焦*
读线(文件*fp,int最大长度)
{
//通过输入临时值扩展大小
char*str;
char*tmp;
int-ch;
int len=0;
int电流_max=0;
//假设我们会得到EOF
str=NULL;
而(1){
ch=fgetc(fp);
如果(ch==EOF)
打破
//如果要以不可见的方式吸收空行,请启用此选项
#如果0
如果(ch='\n')
打破
#恩迪夫
//增加缓冲区
如果(len==当前最大值){
//这个“增长长度”可以是任意数量
电流_max+=10;
tmp=str;
str=realloc(tmp,当前最大值+1);
如果(str==NULL){
免费(tmp);
打破
}
}
//检查换行符
//注意:在realloc之后执行此操作,以区分空行
//来自EOF
#如果1
如果(ch='\n')
打破
#恩迪夫
str[len++]=ch;
}
//将字符串修剪为精确长度,并将EOS添加到字符串中
//注意:修剪是可选的——如果没有修剪,就意味着缓冲区可能会损坏
//比需要的稍大一些
如果(str!=NULL){
#如果1
tmp=str;
str=realloc(str,len+1);
如果(str==NULL)
免费(tmp);
其他的
str[len]=0;
#否则
str[len]=0;
#恩迪夫
}
返回str;
}
建议测试循环停止的原因
为了简洁起见,省略了内存管理
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
/* Utility function to read lines of unknown lengths */
// RETURNS: string pointer (NULL means EOF or realloc failure)
char *
readline(FILE *fp,int max_length)
{
// The size is extended by the input with the value of the provisional
char *str;
char *tmp;
int ch;
int len = 0;
int current_max = 0;
// assume we'll get EOF
str = NULL;
while (1) {
ch = fgetc(fp);
if (ch == EOF)
break;
// enable this if you want to absorb blank lines invisibly
#if 0
if (ch == '\n')
break;
#endif
// grow the buffer
if (len == current_max) {
// this "grow length" can be any amount
current_max += 10;
tmp = str;
str = realloc(tmp,current_max + 1);
if (str == NULL) {
free(tmp);
break;
}
}
// check for newline
// NOTE: do this _after_ the realloc to differentiate a blank line
// from EOF
#if 1
if (ch == '\n')
break;
#endif
str[len++] = ch;
}
// trim string to exact length and add EOS to string
// NOTE: the trim is optional -- without it, it just means the buffer may
// be slightly larger than needed
if (str != NULL) {
#if 1
tmp = str;
str = realloc(str,len + 1);
if (str == NULL)
free(tmp);
else
str[len] = 0;
#else
str[len] = 0;
#endif
}
return str;
}
。因此,问题是您不知道函数如何向其调用者发出信号,表示已到达文件结尾?考虑在任何字符被成功读取之前检测到EOF的情况下返回NULL。在<<代码>中,“”是不必要的(<代码> \n′/COD>是“代码> int <代码> >)。我通常使用
while((ch=fgetc(fp))!=EOF&&ch!='\n')
,尽管这两种命令都有效。最大长度的意义是什么?它不将输入限制为“最大”。最好将其设置为硬最大值,或者让readline()
自行管理增长。@chux这只是为了重用,在实际函数调用中,我只传递硬最大值,定义为源文件开头的宏。很抱歉,如果这造成了混淆,我无法在此处发布完整的源代码。这种方法不区分阅读像“\n”
和EOF
这样的行。两者都返回空字符串。候选简化:if(ch='\n'){str[len++]='\n';str[len]='\0';return(str);}str[len++]=ch代码>-->str[len++]=ch;如果(ch='\n'){break;}
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
/* Utility function to read lines of unknown lengths */
// RETURNS: string pointer (NULL means EOF or realloc failure)
char *
readline(FILE *fp,int max_length)
{
// The size is extended by the input with the value of the provisional
char *str;
char *tmp;
int ch;
int len = 0;
int current_max = 0;
// assume we'll get EOF
str = NULL;
while (1) {
ch = fgetc(fp);
if (ch == EOF)
break;
// enable this if you want to absorb blank lines invisibly
#if 0
if (ch == '\n')
break;
#endif
// grow the buffer
if (len == current_max) {
// this "grow length" can be any amount
current_max += 10;
tmp = str;
str = realloc(tmp,current_max + 1);
if (str == NULL) {
free(tmp);
break;
}
}
// check for newline
// NOTE: do this _after_ the realloc to differentiate a blank line
// from EOF
#if 1
if (ch == '\n')
break;
#endif
str[len++] = ch;
}
// trim string to exact length and add EOS to string
// NOTE: the trim is optional -- without it, it just means the buffer may
// be slightly larger than needed
if (str != NULL) {
#if 1
tmp = str;
str = realloc(str,len + 1);
if (str == NULL)
free(tmp);
else
str[len] = 0;
#else
str[len] = 0;
#endif
}
return str;
}
while((ch = fgetc(fp)) != '\n' && ch != EOF) {
str[len++] = ch;
}
// If _nothing_ read, return NULL
if (len == 0 && ch == EOF) {
return NULL;
}
str[len]= '\0';
return str;