what can be improved?
The contract "scan input to string buffer" and "a function that reads standard input, ignores initial whitespace and fills the buffer with that data." lacks directions on how to handle many cases.
Code appears to be reading until end-of-line, yet that is not specified. Even if so, with ignoring leading white-space, it makes sense to also ignore trailing-white-space including the potential '\n'
.
Appending a '\0'
to insure a string does meet the title requirement. Should anything special happen if a null character '\0'
is read?
Buffer size too small? What to do with extra characters? Consume them, leave them for the next I/O functions?
How to handle an immediate end-of-file? Or an end-of-file after some characters?
How to handle a rare input error?
How to handle pathological input like where == NULL
, size <= 0
?
Array sizes exceeding INT_MAX
?
Perhaps some of these corner case result in a "don't care" or UB as the contract does not specify a behavior. Yet consider a production task with the loose requirements.
Customers expect code to behave well is "all" situations. Although every conceivable issue is a worthy goal and not truly attainable, as an implementor, code should be resilient to many situations. These include ones that are not considered by the customer, yet reasonably possible. For corner cases that significantly reduce performance, greater coding goal detail is needed.
@Roland Illig addresses some coding weakness in OP's code. Some additional ideas:
// Add functional comment
// Return 0 when no data read or error
// int dscan(char *where, int size) {
// Use size_t in and out to convey buffer size and usage
size_t dscan(char *where, size_t size) {
// Assess input values
if (where == NULL || size == 0) {
return 0;
}
// decrement to save space for a \0
size--;
// Read the entire line
// getchar() better than scanf("%c", &c)
// It gets an unsigned char value and indicates end-of-file/error
int c;
size_t i = 0;
size_t non_white_space_next = 0;
while ((c = fgetc(stdin)) != EOF && c != '\n') {
if (i < size) {
if (isspace(c)) {
if (i == 0) continue;
where[i++] = c;
} else {
where[i++] = c;
non_white_space_next = i;
}
} else {
; // What to do with too many characters?
// For now, code will ignore them
// Yet code should convey that buffer was too small.
}
}
// If code is to ignore trailing space
i = non_white_space_next;
// Always append a null character
where[i] = '\0';
// Typically if no characters are read or an error occur,
// code should return 0 to indicate
if (c == EOF && (ferror(stdin) || i == 0)) {
return 0;
}
return i+1;
}