Search code examples
cscanf

fscanf() fails to read


    int ingatlanazonosito, alapterulet, emelet, szobak_szama, rezsi, berleti_dij;
    double x, y;
    char cim[300], butorozott[13];

    while (fscanf(ingatlanfile,"%d;%[^;];%lf;%lf;%d;%d;%d;%[^;];%d;%d\n",
            &ingatlanazonosito, cim, &x, &y, &alapterulet, &emelet,
            &szobak_szama, butorozott, &rezsi, &berleti_dij) != EOF)
    {
        ingatlanbeszur(&ingatlanok, ingatlanazonosito, cim, x, y,
            alapterulet, emelet, szobak_szama, butorozott, rezsi,
            berleti_dij);
    }

I have a problem with the code listed above, the problem is fscanf fails to read the second string (%[^;]) and everything after it. I open the files correctly and everything before the second string is correct. The butorozott string is full of \0 s. This is in the ingatlanfile text file:

123456;Irinyi Jozsef u.;47.473;19.053;18;15;butorozott;1000;9500

How should I solve this?


Solution

  • The input line does not contain 3 integers after the first string, so fscanf fails to convert the 7th field and returns 6 instead of the expected 10 fields.

    Using fscanf to parse input is error prone and does not allow for proper error detection and recovery. You should instead use fgets() to read input one full line at a time, and use sscanf() to attempt the conversion, producing an informative error message in case of failure. Also make sure you prevent buffer overflows by telling scanf() the maximum number of characters to store into the destination arrays for %[ and %s conversions.

        char buf[500];
        int ingatlanazonosito, alapterulet, emelet, szobak_szama, rezsi, berleti_dij;
        double x, y;
        char cim[300], butorozott[13];
    
        while (fgets(buf, sizeof buf, ingatlanfile)) {
            int n = sscanf(buf, "%d;%299[^;];%lf;%lf;%d;%d;%d;%12[^;];%d;%d\n",
                           &ingatlanazonosito, cim, &x, &y, &alapterulet,
                           &emelet, &szobak_szama, butorozott,
                           &rezsi, &berleti_dij);
            if (n != 10) {
                fprintf(stderr, "conversion error for field %d: %s\n", n + 1, buf);
                 continue;  // or some other error recovery decision
            }
            ingatlanbeszur(&ingatlanok, ingatlanazonosito, cim, x, y,
                           alapterulet, emelet, szobak_szama, butorozott,
                           rezsi, berleti_dij);
        }