繁体   English   中英

如果解析为数字而不是字符串,C fscanf报告EOF

[英]C fscanf reports EOF if parsed for a digit but not for a string

我希望将一位数字逐位解析的文件中保留以下文本行:

10001111001000101001010001100000101110000102

但是,当我使用格式说明符%d时,fscanf返回EOF指示符而不是数字。 这与我使用%s的情况形成对比,尽管它一次完成所有操作并以字符串形式返回期望值。

因此,当我更改(以及他从int到char [250]的类型)时,

if (fscanf(f, "%d", &character) != EOF)

if (fscanf(f, "%s", &character) != EOF)

如果要逐位扫描,则需要使用"%1d"作为格式。

否则,它将整行(换行符除外)读取为数字,并在将大十进制数转换为32位int时调用未定义的行为。 请注意,根据普通前缀, d的助记符不是'数字'而是'十进制',而不是'o'代表八进制,'x'代表十六进制,'i'代表十进制,八进制或十六进制的整数(前导0代表八进制, 0x代表十六进制,否则为十进制)。

尚不清楚为什么它返回EOF,但是对于不确定的行为,任何响应都是有效的。

标准(ISO / IEC 9898:2011第7.21.6.2节fscanf()函数 ,第10段)指出(在相关部分中):

如果该对象没有适当的类型,或者无法在对象中表示转换结果,则该行为是不确定的。

关于错误情况下的行为有很多说法,但这是此处的关键。 由于行为是不确定的,因此获得EOF是有效且相对良性的响应。 调查文件流是否处于feof(f)ferror(f)返回true的状态将很有趣。 没有明显的理由应该这样做,除非您通常不会从fscanf()获取EOF,除非其中一个是正确的。

scanf系列函数中的"%d"格式说明符将使该函数查找数字序列,该序列以遇到的第一个非数字字符终止。 在您的情况下,使用"%d"将立即消耗所有数字。

如果"%d"没有这样做,那么您将只能用它读取一位数字,这几乎不是任何格式化输入。

"%s"格式说明符使字符序列被占用,该字符序列将以空格字符或文件结尾终止。

您在这里寻找的是逐字符读取输入的内容。 您可以使用"%c"格式说明符来实现。 之后,您可以将获得的字符解释为数字值。

例如; 您可以读取第一个'1'字符,然后从中减去'0'字符,这将产生'1' - '0' == 1 ,这就是您想要的东西。

fscanf返回失败时分配的输入项目数或EOF 那只是一个问题。 另一个是它将继续使用输入字符串中的字符,直到遇到\\0字符或非数字(在%d情况下)为止。 传递单个字符的地址也不是一件有效的事情。 您可以改为执行以下操作:

char *p;
for (p=&input_string[0]; isdigit(*p); p++) {
    int digit = (int)(*p - '0');
    /* process digit */
}

如果要使用scanf函数之一,请创建一个包含两个字符的字符串-正在处理的数字和\\0 然后sscanf

暂无
暂无

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

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