[英]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.