简体   繁体   中英

Nongreedy fscanf and buffer overflow check in c

I'm looking to have fscanf identify when a potential overflow happens, and I can't wrap my head around how best to do it.

For example, for a file containing the string

**a**bb**cccc**

I do a

char str[10];
while (fscanf(inputf, "*%10[^*]*", str) != EOF) {

}

because I'm guaranteed that what is between ** and ** is usually less than 10. But sometimes I might get a

**a**bb**cccc*

(without the last *) or even potentially a buffer overflow.

I considered using

while (fscanf(inputf, "*%10[^*]", str) != EOF) {

}

(without the last *) or even

while (fscanf(inputf, "*%10s*", str) != EOF) {

}

but that would return the entire string. I tried seeing if I could check for the presence or lack of a *, but I can't get that to work. I've also seen implementation of fgets, but I'd rather not make it complicated. Any ideas?

While fscanf() seems to have been designed as a general purpose expression parser, few programmers rely on that ability. Instead, use fgets() to read a text line, and then use a parser of your choosing or design to dissect the text buffer.

Using the full features of fgets() is dodgy on different implementations and doesn't always provide full functionality, nor even get those implemented right.

I'm not clear on exactly what you want. Is it to skip over any number of stars, and then read up to 9 non-star characters into a buffer? If so, try this:

void read_field(FILE *fin, char buf[10])
{
    int c;
    char *ptr = buf;
    while ((c = getc(fin)) == '*')
        /*continue*/;
    while (c != '*' && c != EOF && ptr < buf+9)
    {
        *ptr++ = c;
        c = getc(fin);
    }
    *ptr = '\0';
    /* skip to next star here? */
}

You will note that I am not using fscanf . That is because fscanf is nearly always more trouble than it's worth. The above is more typing, but I can be confident that it does what I described it as doing.

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