The %d
conversion format ignores leading white space as well as an optional +
sign. If you want a stricter validation, you can:
- use an extra validation phase before or after converting the values.
- use a hand coded conversion that rejects malformed input.
Here are some propositions:
#include <stdio.h>
#include <string.h>
int main() {
char input[100];
char verif[100];
int a, b, c;
if (fgets(input, sizeof input, stdin)) {
if (sscanf(input, "%d,%d,%d", &a, &b, &c) == 3) {
snprintf(verif, sizeof verif, "%d,%d,%d\n", a, b, c);
if (strcmp(input, verif) == 0) {
printf("input is valid, a=%d, b=%d, c=%d\n", a, b, c);
return 0;
} else {
printf("input contains extra characters\n");
return 1;
}
} else {
printf("input does not match the pattern\n");
return 1;
}
} else {
printf("no input\n");
return 1;
}
}
You could just check if the input string contains any white space:
if (input[strcspn(input, " \t")] != '\0') {
printf("input string contains spaces or TABs\n");
}
But negative values, redundant +
signs and leading zeroes will pass the test (eg: "-1,+1,+0001"
).
If all values must be positive, you could use scanf()
to perform a poor man's pattern matching:
if (fgets(input, sizeof input, stdin)) {
char c1, c2;
if (sscanf(input, "%*[0-9],%*[0-9],%*[0-9]%c%c", &c1, &c2) == 1 && c1 == '\n') {
/* input line contains exactly 3 numbers separated by a `,` */
} else {
printf("invalid format\n");
}
}
Note however these remarks:
- redundant leading zeroes would still be accepted by this validation phase (eg:
"00,01,02"
).
- overlong numbers will technically cause undefined behavior in all of the above methods (eg:
"0,0,999999999999999999999999999999"
), But the first approach will detect this problem if the conversion just truncates or maximises the converted value.
- an overlong input line (longer than 98 bytes plus a newline) will be truncated by
fgets()
, leaving the rest of the input for the next read operation. This may be a problem too.
The solution to your problem depends on how strict and concise the validation must be.