繁体   English   中英

在不使用getc的情况下使用fscanf直到EOF

[英]Using fscanf until EOF without using getc

我有一个由2个字节的序列组成的文本文件,必须将其存储在数组中。

我已经声明了FILE *ptr

我如何不使用方法就循环到EOF:

while(c = getc() != EOF)
{
// do something 
}

我想按照(PSEUDOCODE)实现一些东西:

while (ptr is not pointing to the end of the file)
{
fscanf(...)  // I will read in the bytes etc.
}

getc()方法对我来说效果不佳,因为我一次读取的是2个字节的块。

您可以使用fread读取多个字节。 fread返回它能够读取的项目数。

例如,要读取2字节的块,可以使用:

while ((fread(target, 2, 1, ptr) == 1) {
    /* ... */
}

这里2是每个“项目”中的字节数,而1是要在每次调用中读取的“项目”数。

通常,您不应使用feof()控制何时终止输入循环。 使用您正在使用的任何输入例程返回的值。 不同的输入功能在它们提供的信息方面有所不同。 您必须阅读所用文档的文档。

请注意,这会将行尾视为单个'\\n'字符。 您说您正在从文本文件中读取; 尚不清楚您要如何处理行尾。 如果文件的字符数为奇数,则还应该确定要执行的操作。

另一种选择是在循环中两次调用getc()两次检查其结果。

判断何时到达文件末尾的唯一方法是尝试读取过去,但读取失败。 (是的,有一个feof()函数,但是仅您尝试读取文件末尾之后才返回true。)

这意味着,如果要使用fscanf()读取输入,则需要检查的是fscanf()本身的返回值。

具体来说, fscanf()返回已成功读取的项目数,如果输入在可以读取任何内容之前结束,则返回EOF (这是一个负值,通常为-1)。 因此,您的输入循环可能看起来像这样:

while (1) {
    /* ... */

    int n = fscanf(ptr, "...", ...);

    if (n == EOF && !ferror(ptr)) {
        /* we've reached the end of the input; stop the loop */
        break;
    } else if (n < items_requested) {
        if (ferror(ptr)) perror("Error reading input file");
        else fprintf(stderr, "Parse error or unexpected end of input!\n");
        exit(1);  /* or do whatever you want to handle the error */
    }

    /* ... */
}

也就是说,可能还有其他选择。 例如,如果您的输入被构造为行(很多文本输入是行), 则最好通过fgets()逐行读取输入,然后使用sscanf()解析行。

此外,技术上, 偷看前面输入一个字节的方式,使用ungetc() 也就是说,您可以执行以下操作:

int c;
while ((c = getc(ptr)) != EOF) {
    ungetc(c, ptr);
    /* ... now read and parse the input ... */
}

问题在于,这只会检查您是否可以在EOF之前再读取一个字节。 它没有, 也不能 ,实际上检查您的fscanf()调用是否具有足够的数据来匹配所有请求的项。 因此,无论如何,您仍然仍然需要检查fscanf()的返回值-如果要执行此操作,也可以将其用于EOF检测。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM