When I take a vale from stdin
that is to large for c
the reset is not behaving as expected. The user will be re-prompted to input the code but after inputing an additional new line is presented where input is needed, than the length check is failed.
void clear(void) {
while (getchar() != '\n')
;
}
int add_flight(code_t codes[], int lf) {
char c[MAX_CODE_LEN + 1];
int s = 0;
while (s == 0) {
printf("Enter code>\n");
if (fgets(c, sizeof c, stdin)) {
printf("%s", c);
if ('\n' == c[0]) {
printf("Invalid input\n");
} else if (c[sizeof c - 1] == '\0' && c[sizeof c - 2] != '\n') {
clear();
printf("Invalid input\n");
memset(c, 0, sizeof c);
} else {
strcpy(codes[lf].id, c);
s = 1;
break;
}
}
}
return 0;
}
Any help would be greatly appreciated.
There are several problems in your code:
clear
function does not test for end of file, causing an infinite loop if standard input is closed without a trailing newline, as would be the case when redirecting input from an empty file.strlen(c) == sizeof(c) - 1
after stripping the trailing newline.c
is a very confusing name for a char
array. This name is commonly used for an int
to receive a byte value. Name the array buf
for better readability.memset
is useless as you are going to read a new line into the array.code_t
is missing. If the size of its id
member array is not at least MAX_CODE_LEN + 1
, the behavior would be undefined.codes[lf].id
which is probably incorrect.id
is defined to hold MAX_CODE_LEN
characters, ie char id[MAX_CODE_LEN + 1];
for the extra null terminator, buf
should have one extra byte for the newline typed by the user, hence char buf[MAX_CODE_LEN + 2];
Here is a modified version:
int clear(void) {
int c;
while ((c = getchar()) != EOF && c != '\n')
continue;
return c;
}
int add_flight(code_t codes[], int lf) {
char buf[MAX_CODE_LEN + 2];
for (;;) {
printf("Enter code>\n");
if (fgets(buf, sizeof buf, stdin)) {
printf("%s", buf);
/* remove the trailing newline if present */
size_t len = strlen(buf);
if (len > 0 && buf[len - 1] == '\n')
buf[--len] = '\0';
if (len == sizeof(buf) - 1) {
/* line too long: consume the rest of the input line */
printf("Invalid input\n");
if (clear() == EOF)
break;
} else if (len == 0) {
/* empty line */
printf("Invalid input\n");
} else {
strcpy(codes[lf].id, buf);
return 1; // return success
}
} else {
break;
}
}
return 0; // premature end of file: return failure
}