Please also check what the scanf() function returns: it is the number of successful conversions.
(Except that the standards committee goofed, so now some implementations count the special %n pattern, while others do not. Fortunately, %n never ever assigns a negative value, so you can avoid that by assigning -1 to the int variable before scanning.)
Also, if you do not specify the maximum length for %s, scanf() might overrun your buffer, and write garbage over your other variables. If you have an array of 50 characters, use %49s; the 50th one is reserved for the NUL character, '\0', that signifies the end of the string in C.
If other words, use either
Code:
char name[100];
int namelen;
if (scanf("%99s", name) != 1) {
printf("Hey, no input!\n");
exit(EXIT_FAILURE);
}
namelen = strlen(name);
or
Code:
char name[100];
int namelen;
namelen = -1;
(void)scanf("%99s%n", name, &namelen);
if (namelen < 1) {
printf("No input!\n");
exit(EXIT_FAILURE);
}
I am literally distraught how tutors and teachers do not bother with the scanf() family of functions' return value. It causes all sorts of weird issues, when the input is unexpected -- say, instead of a zero, you accidentally type in an O, and don't even notice it yourself.
The easy way is always, always check the number of conversions done. (That abovementioned %n is the annoying exception.)
For example, if you tell the user to input number pairs, and anything else to end the loop, you can do
Code:
double x, y;
while (1) {
if (scanf(" %lf %lf", &x, &y) != 2) {
printf("That was not a number pair, so we're done. Thanks anyway!\n");
break;
}
/* Do something with x and y */
}
See? It's not difficult, and makes your program very robust against incorrect inputs.
If you wanted to be real nice and friendly with those number pairs, pros do it like this:
Code:
char linebuf[128], *line;
double x, y;
while (NULL != (line = fgets(linebuf, sizeof linebuf, stdin))) {
if (sscanf(line, " %lf %lf", &x, &y == 2 ||
sscanf(line, " %lf , %lf", &x, &y == 2 ||
sscanf(line, " [ %lf %lf ]", &x, &y == 2 ||
sscanf(line, " [ %lf , %lf ]", &x, &y == 2 ||
sscanf(line, " ( %lf %lf )", &x, &y == 2 ||
sscanf(line, " ( %lf , %lf )", &x, &y == 2) {
/* You have x and y! */
} else {
/* This removes trailing newline. It's just a neat trick. */
line[strcspn(line, "\n")] = '\0';
printf("%s did not contain two numbers.\n", line);
}
}
Unlike plain scanf(), this latter one reads each line into a buffer (assumes less than 127 characters on each line), then tries the scanning pattern (until one works and reads the two numbers), or complains about the line. This can handle many different forms, like [1.2, 5] for example, and you can add any forms you think your users might try by just adding more sscanf() lines. (They are evaluated one by one, until one matches; the rest are then not tried.)
None of this is advanced stuff. You cannot tack on robustness and error checking after the fact in any kind of reliable manner; you should always think it in, bake it into the recipe, and be happy that you know your program can handle small user errors in a friendly manner.
Thank you for reading. End of rant.