X-Authentication-Warning: delorie.com: mail set sender to djgpp-workers-bounces using -f X-Recipient: djgpp-workers AT delorie DOT com Date: Sat, 22 Dec 2012 10:27:30 +0200 From: Eli Zaretskii Subject: Re: Implementation of %n$ conversion specifier for scanf family of functions. In-reply-to: <50D4FBCF.2060706@gmx.de> X-012-Sender: halo1 AT inter DOT net DOT il To: djgpp-workers AT delorie DOT com Message-id: <8338yyqyod.fsf@gnu.org> References: <50D4FBCF DOT 2060706 AT gmx DOT de> Reply-To: djgpp-workers AT delorie DOT com Errors-To: nobody AT delorie DOT com X-Mailing-List: djgpp-workers AT delorie DOT com X-Unsubscribes-To: listserv AT delorie DOT com Precedence: bulk > Date: Sat, 22 Dec 2012 01:16:15 +0100 > From: Juan Manuel Guerrero > > The patch below will implement the C99 numeric conversion specifier aka %n$ for > the scanf family of functions. Thanks. > +@findex _doscan AT r{, and @acronym{C99} numeric conversion specifiers} > +@findex scanf AT r{, and @acronym{C99} numeric conversion specifiers} > +The @code{%n$} numeric conversion specifiers are now supported > +by @code{_doscan} and the @code{scanf} family of functions. The use of "n" in "%n$" may mislead the reader to think it's a literal "n" meant here. I suggest to use @var{n} instead, or even something like @var{param-no}. > +@samp{[} also skip leading whitespace automatically. > +Conversions can be applied to the nth argument after the format in the > +argument list, rather than to the next unused argument. In this case, > +the conversion specifier character @code{%} is replaced by the sequence > +@code{%n$}, where @code{n} is a decimal integer in the range [@code{1}, @code{number of the last argument}]. ^ ^^^^^^^^ @var{n} and @code{@var{n}}, respectively. And again, maybe don't use "n" at all, but something more descriptive. > +the format string more than once. The format can contain either form of > +a conversion specification - that is, @code{%} or @code{%n$} - but the two Don't use a single "-" character in Texinfo -- that typesets as a minus sign, which is not what you want. For em-dash, use "---", 3 dashes in a row, which will produce what you want both in Info and in the printed manual. > +forms cannot be mixed within a single format string. The only exception > +to this is that @code{%%} or @code{%*} can be mixed with the @code{%n$} > +form. When numbered argument specifications are used, specifying the > +Nth argument requires that all the leading arguments, from the first > +to the (N-1)th, are pointers. Here, again, use @var{n} in all instances, including in "(N-1)th". Do NOT up-case "n", since @var will do that for you automatically. > +/* Test the n$ numeric conversion specifier. */ > + > +#include > + > +int main(void) > +{ > + const char *buffer[3] = { > + "Fecha y hora es: 21 de deciembre de 2012, 01:02:03", > + "Datum und Uhrzeit ist: 21. Dezember 2012, 01:02:03", > + "Date and hour is: december 21 2012, 01:02:03" > + }; > + const char *format[3] = { > + "%*[A-Za-z :] %3$d %*[a-z] %2$9c %*[a-z] %1$d %*[,] %4$d%*[:] %5$d%*[:] %6$d%*", > + "%*[A-Za-z :] %3$d %*[.] %2$8c %1$d %*[,] %4$d%*[:] %5$d%*[:] %6$d%*", > + "%*[A-Za-z ]%*[:] %2$8c %3$d %1$d %*[,] %4$d%*[:] %5$d%*[:] %6$d%*" > + }; > + const char *language[3] = { > + "spanish", > + "german", > + "english" > + }; > + char month[10]; > + int year, day, hour, min, sec, i; > + > + > + for (i = 0; i < (sizeof buffer / sizeof buffer[0]); i++) > + { > + sscanf(buffer[i], format[i], &year, month, &day, &hour, &min, &sec); > + if (i == 0) > + month[9] = '\0'; > + else > + month[8] = '\0'; > + printf("Result of scanf using %s format\n\"%s\":\n" > + " year: %d\n" > + " month: %s\n" > + " day: %d\n" > + " hour: %d\n" > + " min: %d\n" > + " sec: %d\n", language[i], format[i], year, month, day, hour, min, sec); > + } > + > + return 0; > +} It would be better to include the expected results in the program, instead of relying on a human eye to detect errors. Thanks again for working on this.