Ex24: fscanf issue

Please see the picture for the output of ex24. If I type 3f for the age, it seems that fscanf can catch 3 and leave f there which cause the error on the next check. Is there a way to let next fscanf start to scan on the next newline instead of keeping scanning the remainder from the previous line?

I guess I can just use fgetc as ex25 did…

Yes, actually I think this code may be functioning correctly as it’s detecting that you didn’t enter a number when you should have. 3f is not a value number for an age, so that’s a good error. What did you expect.

Actually, it is the color of eyes that caused error, not the age. It seems that it take f as an input for eyes color. If it was the problem of age input, the remaining text would not be printed. Also, I check the line number, which also indicates color input caused error.

Also, I think even if the above problem is gone, check wouldn’t be able to catch input error like “3f” since it correctly catch 3 which makes rc = 1 and then pass the check function.

Maybe it is better to use fgets + sscanf instead of using fscanf in this case. https://stackoverflow.com/questions/865335/when-why-is-it-a-bad-idea-to-use-the-fscanf-function

This can solve initial problem, but the above error remains.

Well, now you have to post your code so we can see why it’s like that. I suspect your code is wrong, not fscanf.

#include <stdio.h>
#include "dbg.h"

#define MAX_DATA 100

typedef enum EyeColor {
    BLUE_EYES, GREEN_EYES, BROWN_EYES,
    BLACK_EYES, OTHER_EYES
} EyeColor;

const char *EYE_COLOR_NAMES[] = {
    "Blue", "Green", "Brown", "Black", "Other"
};

typedef struct Person {
    int age;
    char first_name[MAX_DATA];
    char last_name[MAX_DATA];
    EyeColor eyes;
    float income;
} Person;

int main(int argc, char *argv[])
{
    Person you = {.age = 0 };
    int i = 0;
    char *in = NULL;

    printf("What's your First Name? ");
    in = fgets(you.first_name, MAX_DATA - 1, stdin);
    check(in != NULL, "Failed to read first name.");

    printf("What's your Last Name? ");
    in = fgets(you.last_name, MAX_DATA - 1, stdin);
    check(in != NULL, "Failed to read last name.");

    printf("How old are you? ");
    int rc = fscanf(stdin, "%d", &you.age);
    check(rc > 0, "You have to enter a number.");

    printf("What color are your eyes:\n");
    for (i = 0; i <= OTHER_EYES; i++) {
        printf("%d) %s\n", i + 1, EYE_COLOR_NAMES[i]);
    }
    printf("> ");

    int eyes = -1;
    rc = fscanf(stdin, "%d", &eyes);
    check(rc > 0, "You have to enter a number.");

    you.eyes = eyes - 1;
    check(you.eyes <= OTHER_EYES
            && you.eyes >= 0, "Do it right, that's not an option.");

    printf("How much do you make an hour? ");
    rc = fscanf(stdin, "%f", &you.income);
    check(rc > 0, "Enter a floating point number.");

    printf("----- RESULTS -----\n");

    printf("First Name: %s", you.first_name);
    printf("Last Name: %s", you.last_name);
    printf("Age: %d\n", you.age);
    printf("Eyes: %s\n", EYE_COLOR_NAMES[you.eyes]);
    printf("Income: %f\n", you.income);

    return 0;
error:

    return -1;
}

Sorry, the code format is strange, but it’s exactly the same as your code. Above is the output.

Yes, when you post code put this around it:

[code]
// your code here
[/code]

I did that for you.

Alright looking at your code this is the correct behavior. You are telling fscanf to get an integer. You then enter in SOMETHING THAT IS NOT AN INTEGER. 3f is not an integer. It then produces an error which is the correct thing to do.

Why do you insist on entering 3f? 38, 49, 12. Those are integers. 3f is just … junk?