Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
953 views
in Technique[技术] by (71.8m points)

c - Using fscanf() vs. fgets() and sscanf()

In the book Practical C Programming, I find that the combination of fgets() and sscanf() is used to read input. However, it appears to me that the same objective can be met more easily using just the fscanf() function:

From the book (the idea, not the example):

int main()
{
    int age, weight;
    printf("Enter age and weight: ");

    char line[20];
    fgets(line, sizeof(line), stdin);
    sscanf(line, "%d %d", &age, &weight);

    printf("
You entered: %d %d
", age, weight);
    return 0;
}

How I think it should be:

int main()
{
    int age, weight;
    printf("Enter age and weight: ");
    fscanf(stdin, "%d %d", &age, &weight);

    printf("
You entered: %d %d
", age, weight);
    return 0;
}

Or there is some hidden quirk I'm missing?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

There are a few behavior differences in the two approaches. If you use fgets() + sscanf(), you must enter both values on the same line, whereas fscanf() on stdin (or equivalently, scanf()) will read them off different lines if it doesn't find the second value on the first line you entered.

But, probably the most important differences have to do with handling error cases and the mixing of line oriented input and field oriented input.

If you read a line that you're unable to parse with sscanf() after having read it using fgets() your program can simply discard the line and move on. However, fscanf(), when it fails to convert fields, leaves all the input on the stream. So, if you failed to read the input you wanted, you'd have to go and read all the data you want to ignore yourself.

The other subtle gotcha comes in if you want to mix field oriented (ala scanf()) with line oriented (e.g. fgets()) calls in your code. When scanf() converts an int for example, it will leave behind a on the input stream (assuming there was one, like from pressing the enter key), which will cause a subsequent call to fgets() to return immediately with only that character in the input. This is a really common issue for new programmers.

So, while you are right that you can just use fscanf() like that, you may be able to avoid some headaches by using fgets() + sscanf().


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...