There is a difference in the scansets %1[x+-/]
and %1[x/+-]
. The first will also accept ,
and .
but the second rejects those characters.
#include <stdio.h>
#include <stdlib.h>
char scanoperator ( ) {
int scanned = 1;
char operator[2] = "";
char nl[2] = "";
do {
if ( ! scanned) {
printf ( "try again\n");
}
scanned = scanf ( "%1[x+-/]", operator);
if ( EOF == scanned) {
fprintf ( stderr, "EOF\n");
exit ( 1);
}
scanf ( "%*[^\n]"); // scan and discard everything not a newline
scanf ( "%1[\n]", nl); // scan a newline
} while ( ! scanned);
return operator[0];
}
char scanop ( ) {
int scanned = 1;
char operator[2] = "";
char nl[2] = "";
do {
if ( ! scanned) {
printf ( "try again\n");
}
scanned = scanf ( "%1[x/+-]", operator);
if ( EOF == scanned) {
fprintf ( stderr, "EOF\n");
exit ( 1);
}
scanf ( "%*[^\n]"); // scan and discard everything not a newline
scanf ( "%1[\n]", nl); // scan a newline
} while ( ! scanned);
return operator[0];
}
int main ( void) {
char op;
printf ( "Select the operator((+ - x /)\n");
op = scanoperator ( );
printf ( "operator is %c\n", op);
printf ( "Select the operator((+ - x /)\n");
op = scanop ( );
printf ( "operator is %c\n", op);
return 0;
}
The output from the above code is:
Select the operator((+ - x /)
.
operator is .
Select the operator((+ - x /)
.
try again
The call to scanoperator ()
accepts a .
.
The call to scanop ( )
responds correctly with try again
.
Why is there any difference in these scansets?
C 2024 7.23.6.3 says:
… If a
-
character is in the scanlist and is not the first, nor the second where the first character is a^
, nor the last character, the behavior is implementation-defined…
In %1[x/+-]
, the -
is the last character, so the characters x
, /
, +
, and -
are accepted.
In %1[x+-/]
, the -
is not the first, second, or last character, so the behavior is implementation-defined. Most commonly, the behavior is that a-b
represents the set of characters from a
to b
in the execution character set, inclusive. If the execution character set is ASCII or an extension of it, then the characters from +
to /
are +
(character code 43), ,
(44), -
(45), .
(46), and /
(47). In such implementations, %1[x+-/]
will accept those characters and x
.