Say I have a file dog.txt
The quick brown fox jumps over the lazy dog.
I can read from the file like this
# include <stdio.h>
int main(){
char str[10];
FILE *fp;
fp = fopen("dog.txt", "r");
fscanf(fp, "%[ABCDEFGHIJKLMNOPQRSTUVWXYZ]", str);
printf("%s\n", str);
return 0;
}
and the program will output T. However instead of listing all the letters, can I utilize the POSIX Character Classes, something like [:upper:] ?
No, there's no portable way to do it. Some implementations allow you to use character ranges like %[A-Z], but that's not guaranteed by the C standard. C99 §7.19.6.2/12 says this about the [ conversion specifier (emphasis added):
The conversion specifier includes all subsequent characters in the
formatstring, up to and including the matching right bracket (]). The characters between the brackets (the scanlist) 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. 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.
The POSIX.1-2008 description has almost identical wording (and even defers to the ISO C standard in case of accidental conflict), so there are no additional guarantees in this case when using a POSIX system.
No, you can't. This is what you can do with []:
The conversion specification includes all subsequent bytes in the format string up to and including the matching <right-square-bracket> ('
]'). The bytes between the square brackets (the scanlist) comprise the scanset, unless the byte after the <left-square-bracket> is a <circumflex> ('^'), in which case the scanset contains all bytes that do not appear in the scanlist between the and the <right-square-bracket>. If the conversion specification begins with "[]" or "[^]" , the <right-square-bracket> is included in the scanlist and the next <right-square-bracket> is the matching <right-square-bracket> that ends the conversion specification; otherwise, the first <right-square-bracket> is the one that ends the conversion specification. If a '-' is in the scanlist and is not the first character, nor the second where the first character is a '^' , nor the last character, the behavior is implementation-defined.
(POSIX standard for scanf. The C standard has similar wording, see Adam Rosenfield's answer.)
So, depending on the implementation, you might be able to do fscanf(fp, "%[A-Z]", str), but there's no guarantee that that will work on any POSIX system. In any case, [:upper:] is the same as [:epru].
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With