Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/66.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 读取未知行长度的文件时确定EOF_C_File_File Io_Io - Fatal编程技术网

C 读取未知行长度的文件时确定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

我有上面的代码片段来读取长度未知的行。我能够像预期的那样从stdin读取单行输入,但是在读取文件时,我在确定文件的EOF时遇到了麻烦

在读取文件时,我在循环中逐行读取它,现在我想在读取所有行后中断循环,但我无法确定何时执行,因此循环将永远执行。请帮我确定断裂条件

/* 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;