The problem is that the statement
scanf("%d", &number);
will leave the newline character on the input stream, whereas the statement
fgets(students[i].fullName, sizeof(students[i].fullName), stdin);
will read an entire line of input including the newline character (assuming that the supplied memory buffer is large enough to store the entire line).
You appear to be attempting to compensate for the fact that scanf leaves the newline character on the input stream by using the statement
getchar();
in several places in your code to read and discard the newline character. However, you are not doing this correctly.
If the user enters a number below 1000 for the statement
scanf("%d", &number);
then you will execute the statement
getchar();
twice afterwards, because that statement is in two places in your posted code. This means that it will probably read the newline character as well as the first character of the next line of input of the user.
This explains why in the first loop iteration, students[i].fullName is missing the first character.
In order to fix this, I suggest that you always have the statement
getchar();
either
- immediately after every
scanf function call, or
- immediately before every
fgets function call.
The problem in your posted code is that you are doing a mixture of both.
Note that solution #2 will only work if the first statement in the program is a scanf statement, because if the first statement is a fgets statement, then there will be no newline character to remove. For this reason, it would probably be better to use solution #1.
Also, using the statement
getchar();
will only work if scanf left over only a newline character. However, if the user for example enters
6abc
then the %d format specifier of scanf will only match 6, but will leave abc\n on the input stream. In that case, it would be necessary to call getchar() four times instead of only once.
For this reason, it is generally better to use the following loop instead:
int c;
do
{
c = getchar();
} while ( c != EOF && c != '\n' );
This loop can be shortened to the following two lines:
for ( int c; ( c = getchar() ) != EOF && c != '\n' )
;
If you use this several times in your program, it may be easier to simply write your own function:
void discard_remainder_of_line()
{
int c;
do
{
c = getchar();
} while ( c != EOF && c != '\n' );
}
That way, you only have to write
discard_remainder_of_line();
after every scanf statement.
It would also be safer to always check the return value of scanf before using the result of scanf.
#includedirectives the exact input required to reproduce the problem, and, in this case, also includes the definition ofstruct studentInfo. This allows other people to easily test your program, by simply using copy&paste."the output does not contains first character of the first student name"-- What output? Your posted code does not contain any attempt of printing the first student's name. Please provide a minimal reproducible example of the problem and specify exactly the input, desired output and actual output.sscanf().students[i].fullNameis an array and not a pointer and that is has a sufficient size to accomodate the input. It is also necessary to speculate that all necessary#includedirectives are being used, so that the compiler is not using any implicit declarations (which may cause the compiler to make false assumptions on the parameter types or the return values).