Beginner with C here. I am trying to run a loop where strings and ints
are entered into various fields of a struct
. When prompted for a 'last name', the user can press enter with no other input and the loop should end.
The problem is that with this code, the loop doesnt end (last name and first name entry requests run together on the same line) and the value for salary always comes out wrong (0 or some large number)
while (employee_num <= 2)
{
printf("Enter last name ");
fgets(employee[employee_num].last_name, sizeof(employee[employee_num].last_name), stdin);
if(strlen(employee[employee_num].last_name) == 0)
break;
printf("Enter first name ");
fgets(employee[employee_num].first_name, sizeof(employee[employee_num].first_name), stdin);
printf("Enter title ");
fgets(employee[employee_num].title, sizeof(employee[employee_num].title), stdin);
printf("Enter salary ");
fgets(strng_buffer, 1, stdin);
sscanf(strng_buffer, "%d", &employee[employee_num].salary);
++employee_num;
getchar();
}
If I try this code instead, I am able to exit the loop properly after the first run through it, but cannot exit after that (by pressing enter at the last name portion - perhaps a \n I cant seem to clear?):
char strng_buffer[16];
while (employee_num <= 5)
{
printf("Enter last name ");
fgets(strng_buffer, sizeof(strng_buffer), stdin);
sscanf(strng_buffer, "%s", employee[employee_num].last_name);
if(strlen(employee[employee_num].last_name) == 0)
break;
printf("Enter first name ");
fgets(strng_buffer, sizeof(strng_buffer), stdin);
sscanf(strng_buffer, "%s", employee[employee_num].first_name);
printf("Enter title ");
fgets(strng_buffer, sizeof(strng_buffer), stdin);
sscanf(strng_buffer, "%s", employee[employee_num].title);
printf("Enter salary ");
scanf("%d", &employee[employee_num].salary);
++employee_num;
getchar();
}
I am curious as to how to make this work as intended and what best practice would be for entries like this (ie use of sscanf, fgets, etc)
Thanks in advance!
Assuming the fix mentioned by Abhijit, why transform the first into the second? Are you aware that the second behaves differently to the first, because of the addition of sscanf
? If your intention was to shorten the first, the second seems quite bulky. Rather than adding sscanf
to the situation, why not shorten the first by declaring a struct employee *e = employee + employee_num;
and using that repetitively, instead of employee[employee_num]
?
One "best practise" regarding fgets
is to check it's return value. What do you suppose fgets
might return, if it encounters EOF
? What do you suppose fgets
would return if it's successful?
One "best practise" regarding scanf
is to check it's return value. In regards to the return value of scanf
, I suggest reading this scanf
manual carefully and answering the following questions:
int x = scanf("%d", &employee[employee_num].salary);
What do you suppose x
will be if I enter "fubar\n"
as input?'f'
from "fubar\n"
will go?ungetc
'd back onto stdin
, what would your next employee's last name be?int x = scanf("%d", &employee[employee_num].salary);
What do you suppose x
will be if I run this code on Windows and press CTRL+Z to send EOF
to stdin
?int x = scanf("%d %d", &y, &z);
What would you expect x
to be, presuming scanf
successfully puts values into the two variables y
and z
?P.S. EOF
can be sent through stdin
in Windows by CTRL+Z, and in Linux and friends by CTRL+D, in addition to using pipes and redirection to redirect input from other programs and files.