Thread: fgets is skipping the second time I call it

  1. #1
    Third Eye Babkockdood's Avatar
    Join Date
    Apr 2010
    Posts
    352

    [SOLVED] fgets is skipping the second time I call it

    Hey C Board. I created a typedef structure called Student, and I want to pass this structure to two functions, getStudent, to scanf all the members, and printStudent, to print all the members.

    Code:
    #include <stdio.h>
    
    typedef struct {
    	char name[70];
    	int age;
    	double gpa;
    } Student;
    
    void getStudent(Student *s) {
    	printf("Enter name: ");
    	fgets(s->name, sizeof(s->name), stdin);
    	printf("Enter age: ");
    	scanf("%d", &s->age);
    	printf("Enter GPA: ");
    	scanf("%lf", &s->gpa);
    }
    
    void printStudent(Student *s) {
    	printf("Name: %s", s->name);
    	printf("Age: %d\n", s->age);
    	printf("GPA: %.2f\n", s->gpa);
    }
    
    int main(void) {
    	Student bill, jeff;
    	getStudent(&bill);
    	printf("\n");
    	printStudent(&bill);
    	printf("\n");
    	getStudent(&jeff);
    	printf("\n");
    	printStudent(&jeff);
    	return 0;
    }
    Here's the output. It completely skips the second time I call fgets. What am I doing wrong?

    Code:
    $ ./a.out
    Enter name: James
    Enter age: 20
    Enter GPA: 3.4
    
    Name: James
    Age: 20
    GPA: 3.40
    
    Enter name: Enter age: 22
    Enter GPA: 4.0
    
    Name: 
    Age: 22
    GPA: 4.00
    Last edited by Babkockdood; 04-07-2012 at 10:41 AM.
    Quote Originally Posted by The Jargon File
    Microsoft Windows - A thirty-two bit extension and graphical shell to a sixteen-bit patch to an eight-bit operating system originally coded for a four-bit microprocessor which was written by a two-bit company that can't stand one bit of competition.

  2. #2
    - - - - - - - - oogabooga's Avatar
    Join Date
    Jan 2008
    Posts
    2,808
    The scanf leaves the newline behind. Then the fgets reads only up to the newline, which is nothing.
    If the name does not contain spaces, you could use scanf with "%s".
    If the name can contain a space, then you could use scanf with "%[^\n]".
    The cost of software maintenance increases with the square of the programmer's creativity. - Robert D. Bliss

  3. #3
    Third Eye Babkockdood's Avatar
    Join Date
    Apr 2010
    Posts
    352
    scanf("%[^\n]", s->name) does the same thing.
    Quote Originally Posted by The Jargon File
    Microsoft Windows - A thirty-two bit extension and graphical shell to a sixteen-bit patch to an eight-bit operating system originally coded for a four-bit microprocessor which was written by a two-bit company that can't stand one bit of competition.

  4. #4
    Lurking whiteflags's Avatar
    Join Date
    Apr 2006
    Location
    United States
    Posts
    9,612
    Read all of the input with fgets. You can convert the string to a number if you want, using something like sscanf.

  5. #5
    - - - - - - - - oogabooga's Avatar
    Join Date
    Jan 2008
    Posts
    2,808
    Quote Originally Posted by Babkockdood View Post
    scanf("%[^\n]", s->name) does the same thing.
    Oops. I forgot to mention that you should put a space before it.
    Code:
    scanf(" %[^\n]", s->name);
    The cost of software maintenance increases with the square of the programmer's creativity. - Robert D. Bliss

  6. #6
    Third Eye Babkockdood's Avatar
    Join Date
    Apr 2010
    Posts
    352
    Quote Originally Posted by oogabooga View Post
    Oops. I forgot to mention that you should put a space before it.
    Code:
    scanf(" %[^\n]", s->name);
    That worked, thanks.
    Quote Originally Posted by The Jargon File
    Microsoft Windows - A thirty-two bit extension and graphical shell to a sixteen-bit patch to an eight-bit operating system originally coded for a four-bit microprocessor which was written by a two-bit company that can't stand one bit of competition.

  7. #7
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    The problem with oogabooga's suggestions is that unless you also specify the field width, your code is vulnerable to buffer overflow. fgets does not have this problem since you specify the maximum number of characters to read as an argument.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  8. #8
    - - - - - - - - oogabooga's Avatar
    Join Date
    Jan 2008
    Posts
    2,808
    laserlight is of course correct. And it turns out to be rather ugly to fix without hardcoding the buffer size in the format. Here's a possibility:
    Code:
    #include <stdio.h>
    
    #define STR_SIZE 10
    #define STRINGIZE(x)  STRINGIZE2(x)
    #define STRINGIZE2(x) #x
    
    int main(void) {
        char str[STR_SIZE+1]; // must add 1 here
        scanf(" %" STRINGIZE(STR_SIZE) "[^\n]", str);
        printf("<%s>\n", str);
        return 0;
    }
    But I should have mentioned that reading in lines with fgets and then dealing with them (with sscanf, atoi, etc) is the preferred method.
    The cost of software maintenance increases with the square of the programmer's creativity. - Robert D. Bliss

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Skipping one line using fgets
    By lveenis in forum C Programming
    Replies: 3
    Last Post: 11-25-2011, 03:45 PM
  2. fgets skipping lines
    By wassat676 in forum C Programming
    Replies: 4
    Last Post: 05-29-2011, 11:45 PM
  3. Replies: 4
    Last Post: 05-26-2011, 06:51 AM
  4. fgets skipping, buffer issue?
    By TLW in forum C Programming
    Replies: 2
    Last Post: 02-20-2011, 08:15 PM
  5. fgets and skipping a line...
    By pollypocket4eva in forum C Programming
    Replies: 3
    Last Post: 01-03-2009, 01:42 PM