简体   繁体   中英

In C: Reading integers from a file

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?

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]");

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.

#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;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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