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 addingsscanfto the situation, why not shorten the first by declaring astruct employee *e = employee + employee_num;and using that repetitively, instead ofemployee[employee_num]?One “best practise” regarding
fgetsis to check it’s return value. What do you supposefgetsmight return, if it encountersEOF? What do you supposefgetswould return if it’s successful?One “best practise” regarding
scanfis to check it’s return value. In regards to the return value ofscanf, I suggest reading thisscanfmanual carefully and answering the following questions:int x = scanf("%d", &employee[employee_num].salary);What do you supposexwill be if I enter"fubar\n"as input?'f'from"fubar\n"will go?ungetc‘d back ontostdin, what would your next employee’s last name be?int x = scanf("%d", &employee[employee_num].salary);What do you supposexwill be if I run this code on Windows and press CTRL+Z to sendEOFtostdin?int x = scanf("%d %d", &y, &z);What would you expectxto be, presumingscanfsuccessfully puts values into the two variablesyandz?P.S.
EOFcan be sent throughstdinin 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.