Fgets skipping inputs [duplicate]
Asked Answered
P

1

5

I've tried looking around and I can't seem to find where the error lies. I know it must have something to do with the way I used fgets but I can't figure out for the life of me what it is. I've read that mixing fgets and scanf can produce errors so I've even changed my second scanf to fgets and it still skips the rest of my inputs and only prints the first.

int addstudents = 1;
char name[20];
char morestudents[4];

for (students = 0; students<addstudents; students++)
{
    printf("Please input student name\n");
    fgets(name, 20, stdin);
    printf("%s\n", name);
    printf("Do you have more students to input?\n");
    scanf("%s", morestudents);
    if (strcmp(morestudents, "yes")==0)
    {
    addstudents++;
    }
}

My inputs are Joe, yes, Bill, yes, John, no. All goes according to plan if I utilize scanf in lieu of the first fgets but I would like be able to use full names with spaces included. Where am I going wrong?

Pensionary answered 11/10, 2014 at 19:11 Comment(0)
T
7

When the program displays Do you have more students to input? and you input yes and then hit enter on console, then \n will be stored in input stream.

You need to remove the \n from the input stream. To do that simply call getchar() function.

It will be good if you don't mix scanf and fgets. scanf has lots of problems, better use fgets.

Why does everyone say not to use scanf? What should I use instead?

Try this example:

#include <stdio.h>
#include <string.h>
int main (void)
{
    int addstudents = 1;
    char name[20];
    char morestudents[4];
    int students, c;
    char *p;
    for (students = 0; students<addstudents; students++)
    {
        printf("Please input student name\n");
        fgets(name, 20, stdin);
        //Remove `\n` from the name.
        if ((p=strchr(name, '\n')) != NULL)
            *p = '\0';
        printf("%s\n", name);
        printf("Do you have more students to input?\n");
        scanf(" %s", morestudents);
        if (strcmp(morestudents, "yes")==0)
        {
            addstudents++;
        }
        //Remove the \n from input stream
        while ( (c = getchar()) != '\n' && c != EOF );
    }
    return 0;
}//end main
Tenorrhaphy answered 11/10, 2014 at 19:15 Comment(2)
I would prefer to see: int c; while ((c = getchar()) != EOF && c != '\n') ; where the semicolon for the loop body would be on a line on its own. This protects you if the user types yes please or just puts a space at the end of the input. In this case, it is crucial to use int c instead of char c. In the original code, you don't use c (so my default compiler options would complain about a set but unused variable; I'd end up with (void)getchar(); if I used the code here) so it doesn't matter that you can't reliably distinguish EOF from a valid character.Middling
@JonathanLeffler: I'm glad you gave suggestion for improvement on my post. Thanks :) Made the changes as you have suggested. Updated change will also work if the user inputs yes .Tenorrhaphy

© 2022 - 2024 — McMap. All rights reserved.