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 considerconsidered by the customer, yet reasonably possible. For corner cases that significantly reduce performance, greater coding goal detail is needed.
// 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;
}