所以我被要求在课堂上写一个小程序。我正在学习用C编写代码,当试图根据其类型将值存储在不同的变量中时,我对这个函数和fscanf函数的使用有问题。
它应该做的是由我的老师写在注解中,其余的是我的代码(除了包含的库之外,我不应该使用任何其他库):
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/* A) Tries to read a double from the file and asign its value to the double pointed by num. If it was possible returns 1.
B) In other case, tries to read a string up to 31 chars and stores its value on the string
pointed by op, if it was possible returns 2.
C) In any other case it returns 0 (end of file, etc)*/
int num_or_op(FILE* f, double *num, char *op) {
int aux;
int read = 0;
read = fscanf(f, "%lf", num);
if (read==-1) /*eof*/
return 0;
if (read==0){
aux = fscanf(f, "%31s", op);
if (aux>0){
read=2;
}
}
return read;
}
字符串
我发现的问题是,按照这些步骤,程序跳过了一些字符。我在while块中调用这个函数来存储所有数据。如果我引入一个文件,例如,1 2 + 3,它读取1和2,那么它无法正确存储+
,而是在下一个fscanf中执行,它只是扫描数字3并将其添加到op指向的字符串中。我想当fscanf
返回0时,如果这次格式正确,下一次调用fscanf
会读取之前无法读取的相同字符,但显然它不这样工作,或者我可能做错了什么。我能够想出不同的替代方案,但是有没有办法按照指定的顺序,A,B,C并直接从文件中阅读fscanf(例如,不使用fgets来获取一行)?我被要求用这个特定的功能来做。如果有关系的话,我正在用gcc -ansi -pedantic -Wall -Wextra -Werror -o program program.c
编译。
2条答案
按热度按时间b1payxdu1#
正确答案是由@user3386109在评论中给出的,所以我在这里添加解释以结束这个问题。
在这个函数发生转换错误后,标准只需要一个字符的后推,而我使用的实现满足最低要求的后推。输入
-.a
就是一个很好的例子。解析器需要读取三个字符来确定输入不是有效的double
。如果它只回推一个字符,则-
和.
将丢失。在我的例子中,+
和space被读取,只有space被推回。我的程序运行的是C版本的C89/C90。jdzmm42g2#
你的代码似乎在为我工作:
字符串
使用
1 2 + 3
作为输入:型
再加上一些令人讨厌的输入:
型
也许你的问题是在调用代码?
话虽如此,我确实对你的代码有一些风格上的问题。比如使用
-1
而不是EOF
,或者需要第二个aux
变量,等等。事实证明,该函数可以更清晰:型