Can anyone tell me why it will still repeat the instruction?
The tricky part is that "%d"
consumes leading white-space, so code needs to detect leading white-space first.
" "
consumes 0 or more white-space and never fails.
So "\n%c %d %d"
does not well detect the number of intervening spaces.
If the int
s can be more than 1 character, use this, else see below simplification.
Use "%n
to detect location in the buffer of sscanf()
progress.
It gets the job done using sscanf()
which apparently is required.
// No need for a tiny buffer
char line[80];
if (fgets(line, sizeof line, stdin) == NULL) Handle_EOF();
int n[6];
n[5] = 0;
#define SPACE1 "%n%*1[ ] %n"
#define EOL1 "%n%*1[\n] %n"
// Return value not checked as following `if()` is sufficient to detect scan completion.
// See below comments for details
sscanf(line, "%c" SPACE1 "%d" SPACE1 "%d" EOL1,
&command, &n[0], &n[1],
&x, &n[2], &n[3],
&y, &n[4], &n[5]);
// If scan completed to the end with no extra
if (n[5] && line[n[5]] == '\0') {
// Only 1 character between?
if ((n[1] - n[0]) == 1 && (n[3] - n[2]) == 1 && (n[5] - n[4]) == 1) {
Success(command, x, y);
}
}
Maybe add test to insure command
is not a whitespace, but I think that will happen anyway in command processing.
A simplification can be had if the int
s must only be 1 digit and with a mod combining @Seb answer with the above. This works because the length of each field is fixed in an acceptable answer.
// Scan 1 and only 1 space
#define SPACE1 "%*1[ ]"
int n = 0;
// Return value not checked as following `if()` is sufficient to detect scan completion.
sscanf(line, "%c" SPACE1 "%d" SPACE1 "%d" "%n", &command, &x, &y, &n);
// Adjust this to accept a final \n or not as desired.
if ((n == 5 && (line[n] == '\n' || line[n] == '\0')) {
Success(command, x, y);
}
@Seb and I dove into the need for checking the return value of sscanf()
. Although the cnt == 3
test is redundant since n == 5
will only be true when then entire line was scanned and sscanf()
returns 3, a number of code checkers may raise a flag noting that the results of sscanf()
is not checked. Not qualifying the results of sscanf()
before using the saved variables is not robust code. This approach uses a simple and sufficient check of n == 5
. Since many code problems stem from not doing any qualification, the lack of the check of the sscanf()
can raise a false-positive amongst code checkers. Easy enough to add the redundant check.
// sscanf(line, "%c" SPACE1 "%d" SPACE1 "%d" "%n", &command, &x, &y, &n);
// if (n == 5 && (line[n] == '\n' || line[n] == '\0')) {
int cnt = sscanf(line, "%c" SPACE1 "%d" SPACE1 "%d" "%n", &command, &x, &y, &n);
if (cnt == 3 && n == 5 && (line[n] == '\n' || line[n] == '\0')) {