Reputation: 1668
I have a function that basically read integers from a file:
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);
First I tried with the following file:
5 4
128
My output was correct, as I wanted:
*pm = 4
*pn = 5
*pmax = 128
But the real file is:
P2
5 4
128
I wanted my output to be as the one before, but then I got:
*pm = 0
*pn = 0
*pmax = 0
What went wrong?
Upvotes: 0
Views: 2262
Reputation: 40155
#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;
}
Upvotes: 1
Reputation: 490623
It's trying to read an int
, but getting P
. Since that can't convert to int
, it's left in the stream, and the conversion fails. The same happens for the second and third numbers.
Rereading your input, you probably want to do something like reading a string, then attempting to convert that to an int. You could read with %s
, then convert with strtol
. If that doesn't convert, ignore it and try again.
Upvotes: 2
Reputation: 183978
The file starts
P2
with a letter, not a digit. Thus the fscanf
calls all fail to convert the input to an integer, consuming no input.
You should always check the return value of the scanf
family of functions to catch conversion failures due to malformed input or corrupted streams.
You can skip the first line with, for example,
fscanf(file, "%*[^\n]");
Upvotes: 4