Search code examples
cscanf

Is it possible to specify a string consisting of a number of `^` characters for scanf?


In a C-scanf format, how do I specify, that I want a character ^?

"%[^]" does not work with GNU scanf, because ^ at start has the negation meaning.


Solution

  • scanf is it possible to specify a string consisting of a number of ^ characters?

    Doing a simple %[^] is impossible.

    The %[^] is actually invalid - the initial [ is not closed. A %[^]] is interpreted as all characters except ].

    Assuming %[^] would be valid, then it would present an ambiguity: %[^]] could be interpreted as a string consisting only from ^ followed by a ]. Or imagine like $[^]abc]. I believe the ability to scan strings only consisting of ^ was sacrificed to give ^ its functionality, which makes a reasonable sacrifice.

    To solve the problem in practice, do not use scanf and write it yourself. Or you could do something like "%[\01^] - scan also something else that will not be in the input, like 0x01 byte.

    From C99 7.19.6.2 (and this pdf) (emphasis mine):

    [

    [...]

    The conversion specifier includes all subsequent characters in the format string, up to and including the matching right bracket (]). The characters between the brackets (the scan list) compose the scanset, unless the character after the left bracket is a circumflex (^), in which case the scanset contains all characters that do not appear in the scanlist between the circumflex and the right bracket. 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. [...]

    So if the conversion is %[] or %[^] then the ] is in the scanlist, and the next ] will end the scanlist.

    As a workaround, you can specify in the scanlist ^ negation of all characters except ^, effectively scanning only for ^ - %[^^].