OP: unclear on how getchar()
works
int fgetc(FILE *stream)
typically returns 1 of 257 different values.
"If ... a next character is present, the fgetc
function obtains that character as an unsigned char
converted to an int
C11 §7.21.7.1 2
On end-of-file or input error (rare), EOF
, is returned.
OP: to use getchar()
in my program to read user input instead of fgets
.
Create your own my_fgets()
with the same function signature and same function as fgets()
and then replace.
char *fgets(char * restrict s, int n, FILE * restrict stream);
The fgets
function reads at most one less than the number of characters specified by n
from the stream pointed to by stream into the array pointed to by s
. No additional characters are read after a new-line character (which is retained) or after end-of-file. A null character is written immediately after the last character read into the array. C11 §7.21.7.2 2
Return the same value
The fgets
function returns s
if successful. If end-of-file is encountered and no characters have been read into the array, the contents of the array remain unchanged and a null pointer is returned. If a read error occurs during the operation, the array contents are indeterminate and a null pointer is returned. §7.21.7.2 3
Sample untested code
#include <stdbool.h>
#include <stdio.h>
char *my_fgets(char * restrict s, int n, FILE * restrict stream) {
bool something_read = false;
int ch = 0;
char *dest = s;
// Room ("reads at most one less") and EOF not returned?
while (n > 1 && (ch = fgetc(stream)) != EOF) {
n--;
something_read = true;
*dest++ = (char) ch;
if (ch == '\n') {
break; // "No additional characters are read after a new-line character"
}
}
// Did code end the while loop due to EOF?
if (ch == EOF) {
// Was EOF due to end-of-file or rare input error?
if (feof(stream)) {
// "If end-of-file is encountered and no characters ... read into the array ..."
if (!something_read) {
return NULL;
}
} else {
// "If a read error ..."
return NULL; // ** Note 1
}
}
// room for \0?
if (n > 0) {
*dest = '\0'; //" A null character is written immediately after the last character"
}
return s;
}
Perhaps improve fgets()
and use size_t
for n
.
char *my_fgets(char * restrict s, size_t n, FILE * restrict stream);
fgets()
with n <= 0
is not clearly defined. Using size_t
, an unsigned type, at least eliminates n < 0
concerns.
Note 1: or use s = NULL;
instead of return NULL;
and let the remaining code null terminate the buffer. We have that option as "array contents are indeterminate".