0
votes
float lat, lon;
char info[50];

scanf("%f, %f, %49[^\n]", &lat, &lon, info);

In the above snippet, what kind of format specifier is %49[^\n].

I do understand that it is the format specifier for the character array which is going to accept input upto 49 characters (+ the sentinal \0), and [^\n] looks like its a regex (although I had read somewhere that scanf doesn't support regex) OR a character set which is to expand to "any other character" that is NOT "newline" \n. Am I correct?

Also, why is there no s in the format specifier for writing into array info?

The program this snippet is from works. But is this good C style?

2
Did you read the cppreference page on scanf?HolyBlackCat

2 Answers

1
votes

The specifier %[ is a different conversion specifier from %s, even if it also must be paired with an argument of type char * (or wchar_t *). See e.g. the table here

[set] matches a non-empty sequence of character from set of characters.
If the first character of the set is ^, then all characters not in the set are matched. If the set begins with ] or ^] then the ] character is also included into the set. It is implementation-defined whether the character - in the non-initial position in the scanset may be indicating a range, as in [0-9]. If width specifier is used, matches only up to width. Always stores a null character in addition to the characters matched (so the argument array must have room for at least width+1 characters)

1
votes

My apologies, I incorrectly answered below. If you can skip to the end, I'll give you the correct answer.

*** Incorrect Answer Begins ***

It would not be a proper format specifier, as there is no type.

%[parameter][flags][width][.precision][length]type

are the rules for a format statement. As youc an see, the type is non-optional. The author of this format item is thinking they can combine regex with printf, when the two have entirely different processing rules (and printf doesn't follow regex's patterns)

*** Correct Answer Begins ***

scanf uses different format string rules than printf Within scanf's man page is this addition to printf's rules

[

Matches a nonempty sequence of characters from the specified set of accepted characters; the next pointer must be a pointer to char, and there must be enough room for all the characters in the string, plus a terminating null byte. The usual skip of leading white space is suppressed. The string is to be made up of characters in (or not in) a particular set; the set is defined by the characters between the open bracket [ character and a close bracket ] character. The set excludes those characters if the first character after the open bracket is a circumflex (^). To include a close bracket in the set, make it the first character after the open bracket or the circumflex; any other position will end the set. The hyphen character - is also special; when placed between two other characters, it adds all intervening characters to the set. To include a hyphen, make it the last character before the final close bracket. For instance, [^]0-9-] means the set "everything except close bracket, zero through nine, and hyphen". The string ends with the appearance of a character not in the (or, with a circumflex, in) set or when the field width runs out.

Which basically means that scanf can scan with a subset of regex's rules (the character set subset) but not all of regex's rules