我有一个基本上从文件中读取整数的函数:
FILE *file;
file = fopen("filename.txt", "r");
fscanf(file, "%d", &(*pn));
fscanf(file, "%d", &(*pm));
fscanf(file, "%d", &(*pmax));
printf("*pm = %d\n", *pm);
printf("*pn = %d\n", *pn);
printf("*pmax = %d\n", *pmax);
首先,我尝试使用以下文件:
5 4
128
我的输出是正确的,正如我想的那样:
*pm = 4
*pn = 5
*pmax = 128
但真正的文件是:
P2
5 4
128
我希望我的输出像以前一样,但后来我得到了:
*pm = 0
*pn = 0
*pmax = 0
出了什么问题?
答案 0 :(得分:4)
文件开始
P2
带有一个字母,而不是一个数字。因此,fscanf
调用都无法将输入转换为整数,不会消耗任何输入。
您应该始终检查scanf
系列函数的返回值,以捕获由于输入格式错误或流损坏而导致的转换失败。
您可以跳过第一行,例如
fscanf(file, "%*[^\n]");
答案 1 :(得分:2)
它正在尝试阅读int
,但获取P
。由于无法转换为int
,因此它会保留在流中,转换失败。第二和第三个数字也是如此。
重读您的输入,您可能希望执行类似读取字符串,然后尝试将其转换为int的操作。您可以使用%s
阅读,然后使用strtol
进行转换。如果没有转换,请忽略它并重试。
答案 2 :(得分:1)
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
char *inputString(FILE* fp, size_t size){
//The size is extended by the input with the value of the provisional
char *str;
int ch;
size_t len = 0;
str = realloc(NULL, sizeof(char)*size);//size is start size
if(!str)return str;
while(EOF!=(ch=fgetc(fp)) && isspace(ch));//skip space chars
ungetc(ch, fp);
while(EOF!=(ch=fgetc(fp)) && !isspace(ch)){
str[len++]=ch;
if(len==size){
str = realloc(str, sizeof(char)*(size+=16));
if(!str)return str;
}
}
str[len++]='\0';
return realloc(str, sizeof(char)*len);
}
enum {false, true };
int readInt(FILE *fp, int *n){
char *token, *endp;
long wk;
for(;;){
token = inputString(fp, 16);//separated by space character
if(!*token){//EOF
free(token);
return false;
}
wk = strtol(token, &endp, 0);
if(*endp=='\0')break;//success read int
free(token);
}
*n = (int)wk;
free(token);
return true;
}
int main(void){
FILE *file;
int n, m, max,i;
n = m = max = 0;
file = fopen("filename.txt", "r");
readInt(file, &n);
readInt(file, &m);
readInt(file, &max);
/*
printf("debug:");
if(readInt(file, &i)==false){
printf("false\n");
}
*/
fclose(file);
printf("m = %d\n", m);
printf("n = %d\n", n);
printf("max = %d\n", max);
return 0;
}