0

The following code is supposed to prompt the user for the number of students and number of assignments and then prompt them to enter the name of each student.

When it reaches the loop to ask for student names for some reason it prints the prompt twice on one line

Student name: Student name:

Could someone please tell me why this happens? And how to fix it?

I have run into this issue several times but in different scenarios.

#include <stdio.h>
#include <cstring>

void print_array(char str[20][20], int number) {
    int i;
    for (i=0; i < number; i++) {
        printf("%s\n", str[i]);
    }
    printf("---\n");
}

void main() {
    int students, assignments;
    char names[20][20];

    do {
        printf("How many students are there (between 1 and 20)?");
        scanf("%d", &students);
        if (students < 1 || students > 20)
            printf ("Number of students must be between 1 and 20.\n");
    } while (students < 1 || students > 20);

    do {
        printf("How many assignments are there (between 1 and 10)?");
        scanf("%d", &assignments);
        if (assignments < 1 || assignments > 10)
            printf ("Number of assignments must be between 1 and 10.\n");
    } while (assignments < 1 || assignments > 10);

    int i;
    for(i=0; i < students; i++){
        printf("Student name:");
        fgets(names[i], 20, stdin);
    }

    print_array(names, students);
}
kfsone
  • 23,617
  • 2
  • 42
  • 74
  • Since it's C, then the header should be `string.h` instead of `cstring` – Yu Hao Nov 08 '13 at 08:28
  • my initial guess is that the input buffer is not empty when you call fgets, because scanf has not eaten it all up. so fgets will terminate immediately, using whatever was left (probably empty string) as name, and you get to see the second iteration of the loop. – Andreas Grapentin Nov 08 '13 at 08:32
  • Read about it [here](http://stackoverflow.com/questions/9562218/c-mutliple-scanfs-when-i-enter-in-a-value-for-one-scanf-it-skips-the-second-s) – Suvarna Pattayil Nov 08 '13 at 08:34
  • Your question is unclear. What input are you giving the program? You have the `printf("Student name:");` inside the for loop so it will print it each time. So if you tell it there are 2 students, it will print it once before reading *each* student name. 2 students = 2 prompts. 5 students = 5 prompts. – kfsone Nov 08 '13 at 08:37
  • Sorry, I didn't word the question very well. It prints the statement twice on the before you get the chance to enter a name. I want it so that it prints Student Name: then scans the name each time. – user2967968 Nov 08 '13 at 08:43

1 Answers1

3

When you use scanf to read from the keyboard you need to take into account that it reads everything that you enter from the keyboard, that includes the ENTER key. scanf works with a buffer so when you write "%d" it extracts only that leaving the ENTER in the buffer. Next time you call scanf ENTER is still in the buffer.

Instead use fgets and atoi to read and convert the integer, it is safer and easier to use.

char buffer[32];
fgets(buffer,sizeof(buffer),stdin);
assignments = atoi(buffer);

e.g.

char buffer[32];
do 
{
  printf("How many students are there (between 1 and 20)?");
  fgets(buffer,sizeof(buffer),stdin);
  students = atoi(buffer);
  if (students < 1 || students > 20)
  {
    printf ("Number of students must be between 1 and 20.\n");
  }
} while (students < 1 || students > 20);

or better do a function

int getInt()
{
  char buffer[32];
  fgets(buffer,sizeof(buffer),stdin);
  return atoi(buffer);
}

...

do 
{
  printf("How many students are there (between 1 and 20)?");
  students = getInt();
  if (students < 1 || students > 20)
  {
    printf ("Number of students must be between 1 and 20.\n");
  }
} while (students < 1 || students > 20);
AndersK
  • 35,813
  • 6
  • 60
  • 86
  • "safer" meaning still terribly unsafe, as far as buffer overrun attacks are concerned. *sigh* the wonders of C user input functionality :) (still +1 though) – Andreas Grapentin Nov 08 '13 at 08:35
  • Wow that does make a lot of sense! I am glad you responded. I am the biggest noob ever, how do I use the code you provided? Just rewrite it with my variables? – user2967968 Nov 08 '13 at 08:38
  • I know! I like it too :) – AndersK Nov 08 '13 at 08:46
  • I really appreciate your help but I still dont even know how to use these solutions you have provided. I tried sticking second block of code you provided into my program but its telling me atoi is unidentified – user2967968 Nov 08 '13 at 08:54
  • `#include ` – AndersK Nov 08 '13 at 09:38