I'm trying to use scanf()
to read lines of the form mov r0, r1, r2
or ldr r0, [r1, 0x4]
in a text buffer, negating any possible square brackets, commas and white spaces. The following code is not working:
void ReadBuffer(const char* buffer)
{
char command[2048];
char var[3][2048];
sscanf(buffer,"%[^ ,[]\n\t] %[^ ,[]\n\t], %[^ ,[]\n\t], %[^ ,[]\n\t]", command, va[0], var[1], var[2]);
}
How can I add the square brackets to the negated scanset?
C 2018 describes the scanf
conversion specifiers in 7.21.6.2 12, and for the [
conversion it says:
… If the conversion specifier begins with
[]
or[^]
, the right bracket character is in the scanlist and the next following right bracket character is the matching right bracket that ends the specification; otherwise the first following right bracket character is the one that ends the specification…
Therefore, put the ]
immediately after the ^
. The [
may go anywhere in the scanlist (the characters between the [
and the closing ]
).
Example:
#include <stdio.h>
int main(void)
{
char a[100], b, c[100], d, e[100], f;
int result = sscanf("foo[bar, baz]", " %[^][, ] %c %[^][, ] %c %[^][, ] %c", a, &b, c, &d, e, &f);
printf("scanf returned %d.\n", result);
printf("a = %s.\n", a);
printf("b = %c.\n", b);
printf("c = %s.\n", c);
printf("d = %c.\n", d);
printf("e = %s.\n", e);
printf("f = %c.\n", f);
}
Output:
scanf returned 6. a = foo. b = [. c = bar. d = ,. e = baz. f = ].
Note this is a painstaking way to parse assembly code. It is usually better to write your own C code to analyze the characters, especially after studying some parsing theory, and even better to use an off-the-shelf lexical analyzer generator and a grammar parser generator. Doing it with scanf
requires careful attention to return values, buffer sizes, and more.