I was fooling around with scanf and fgets and came up with this. I think both are as solid as they can get but I'm not 100% sure. Could anyone comment on any problems that they may have or how to improve on them? What I'm going for is foolproof user input.
In the code, rc is defined as an int, buf as a char array with 11 elements, and warn looks like this
Code:
void warn(char *msg)
{
fprintf(stderr, "Warning: %s\n", msg);
}
Ina real program I would switch warn with die as appropriate
Code:
void die(char *msg)
{
fprintf(stderr, "Fatal error: %s\n", msg);
exit(EXIT_FAILURE);
}
First is the scanf method
Code:
rc = scanf("%10[^\n]", buf);
if (rc == EOF)
{
if (feof(stdin))
warn("End of file reached...");
if (ferror(stdin))
warn("I/O error occurred...");
}
else if (rc < 1)
warn("Incorrect input format or no input...");
if (rc >= 0)
{
int n;
scanf("%*[^\n]%n", &n);
getchar();
/* For debugging only */
printf("Extraneous characters: %d\n", n);
}
And the fgets method
Code:
if (fgets(buf, sizeof (buf), stdin) != NULL)
{
char *newline;
if (buf[0] == '\n')
warn("No input processed...");
newline = strrchr(buf, '\n');
if (newline != NULL)
*newline = '\0';
else
{
int n;
scanf("%*[^\n]%n", &n);
getchar();
/* For debugging only */
printf("Extraneous characters: %d\n", n);
}
}
else
{
if (feof(stdin))
warn("End of file reached...");
if (ferror(stdin))
warn("I/O error occurred...");
}
In a real program I'd also either wrap these up in their own functions to make getting a line simpler, or at the very least wrap the error checking into their own functions
Code:
void garbage(FILE *in)
{
int n;
fscanf(in, "%*[^\n]%n", &n);
getchar();
/* For debugging only */
printf("Extraneous characters: %d\n", n);
}
void ioerror(FILE *in)
{
if (feof(in))
warn("End of file reached...");
if (ferror(in))
warn("I/O error occurred...");
}
Or something like that.