I am writing a program which uses fgets() to scan a 3 Char long string as an Airport code for Departure and arrival. When I write the statement outside its method (in the main) it works fine however inside it does not wait for input and leaves the variables blank.
void newFlight ()
{
printf("\n");
printf("============= CREATE A NEW FLIGHT ============= \n");
printf("Type 0 at any point to exit to main menu. \n");
printf("\n");
printf("EnterFlight ID (0 to cancel) : ");
scanf("%d", &flyList[curFly].flightID);
char codeA [4];
printf ("Enter Destination (Airport Code): ");
fgets(codeA, 3, stdin);
strcpy(codeA, flyList[curFly].arrive);
printf("%s %s \n", codeA, flyList[curFly].arrive); //TEST
printf("Enter Place Of Departure: ");
char codeD[4];
scanf("%s", codeD);
strcpy(codeD, flyList[curFly].depart);
printf("%s %s \n", codeD, flyList[curFly].depart); //TEST
printf("Enter Date Of Departure (DD MM YYYY): ");
scanf("%hd %hd %hd", &flyList[curFly].timeOfDep.day, &flyList[curFly].timeOfDep.month, &flyList[curFly].timeOfDep.year);
printf("Enter Time Of Departure (HH MM)in 24Hr Format: ");
scanf("%hd %hd", &flyList[curFly].timeOfDep.hour, &flyList[curFly].timeOfDep.minute);
curFly++;
}
Mixing fgets()
with scanf()
is problematic.
fgets()
consumes the Enter (\n
).
scanf("%d", ...
sees the \n
, which stops the %d
conversion, and puts \n
back into stdin
for the next IO operation - which happend to be OP's fgets()
which returns promptly with a short string.
Also need to check scanf()
results. specifying a width with "%s
is good, like "%3s
.
Quick solution: only using scanf()
// scanf("%d", &flyList[curFly].flightID);
if (1 != scanf("%d", &flyList[curFly].flightID)) handle_error();
...
char codeA [4];
// fgets(codeA, 3, stdin);
if (1 != scanf("%3s", codeA) handle_error();
...
// Likely backwards
// strcpy(codeA, flyList[curFly].arrive);
strcpy(flyList[curFly].arrive, codeA);
...
char codeD[4];
// scanf("%3s", codeD);
if (1 != scanf("%3s", codeD)) handle_error();
...
// scanf("%hd %hd %hd", &flyList[curFly].timeOfDep.day, &flyList ...
if (3 != scanf("%hd %hd %hd", &flyList[curFly].timeOfDep.day, &flyList[curFly].timeOfDep.month, &flyList[curFly].timeOfDep.year)) handle_error();
...
// scanf("%hd %hd", &flyList[curFly].timeOfDep.hour, &flyList ...
if (2 != scanf("%hd %hd", &flyList[curFly].timeOfDep.hour, &flyList[curFly].timeOfDep.minute)) handle_error();
Better solution: use fgets()/sscanf()
// scanf("%d", &flyList[curFly].flightID);
char buf[100];
if (fgets(buf, sizeof buf, stdin) == NULL) Handle_EOForIOError();
if (1 != sscanf(buf, "%d", &flyList[curFly].flightID)) handle_parse_error();
...
if (fgets(buf, sizeof buf, stdin) == NULL) Handle_EOForIOError();
if (1 != sscanf(buf, "%3s", flyList[curFly].arrive) handle_parse_error();
...
etc.
BTW: scanf()
format "%hd %hd"
and "%hd%hd"
do the same thing.