Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Access violation while using fscanf_s

Tags:

c

scanf

I want to read a file in a specific format, so I use fscanf_s and a while loop. But as soon as fscanf_s is processed, the program crashes with an access violation (0xC0000005).

Here's the code:

FILE *fp;
errno_t err = fopen_s(&fp, "C:\\data.txt", "r");

if (err != 0)
    return 0;

int minSpeed = 0;
int maxSpeed = 0;
char axis = '@';

while(!feof(fp)) 
{
    int result = fscanf_s(fp, "%c;%d-%d\n", &axis, &minSpeed, &maxSpeed);

    if (result != 3)
        continue;
}

fclose(fp);

The content of the file is line based, for example:

-;10000-20000
X;500-1000
S;2000-2400

Can somebody help me?

like image 757
Hubert Korn Avatar asked Jan 20 '23 15:01

Hubert Korn


1 Answers

Apparently, fscanf_s() needs a size parameter after the address of the variable

fscanf_s(fp, "%c;%d-%d\n", &axis, 1, &minSpeed, &maxSpeed);
/* extra 1 for the size of the   ^^^ axis array */

But I suggest you do not use the *_s functions: they are worse than the plainly named functions --- they require the same checks and make you feel safe when you aren't. I suggest you don't use them because of false sense of security and the fact they are not available on many implementations making your programs work only in a limited subset of possible machines.

Use plain fscanf()

fscanf(fp, "%c;%d-%d\n", &axis, &minSpeed, &maxSpeed);
/* fscanf(fp, "%1c;%d-%d\n", &axis, &minSpeed, &maxSpeed); */
/* default 1   ^^^    same as for fscanf_s                 */

And your use of feof() is wrong.
The fscanf() returns EOF when there is an error (end-of-file or matching failure or read error ...).

You can use feof() to determine why fscanf() failed, not to check whether it would fail on the next time it is called.

/* pseudo-code */
while (1) {
    chk = fscanf();
    if (chk == EOF) break;
    if (chk < NUMBER_OF_EXPECTED_CONVERSIONS) {
        /* ... conversion failures */
    } else {
        /* ... all ok */
    }
}
if (feof()) /* failed because end-of-file reached */;
if (ferror()) /* failed because of stream error */;
like image 120
pmg Avatar answered Feb 01 '23 08:02

pmg