On Mon, Jun 23, 2008 at 12:37:50PM +0200, Michael Kerrisk wrote:
[...]
>    NOTES
>        The GNU C library supports a non-standard extension that causes
>        the library to dynamically allocate a string of sufficient size
>        for  input  strings  for  the  %s  and   %a[range]   conversion
>        specifiers.  To make use of this feature, specify a as a length
>        modifier (thus %as or %a[range]).  The caller must free(3)  the
>        returned string, as in the following example:
> 
>            char *p;
> 
>            scanf("%a[a-zA-Z]", &p);

You need to check the return value of scanf (could be 0 or EOF,
caused by the absence of letters in the input, or an EOF or read
error or ENOMEM.

>            printf("%s0, p);

typo? printf("%s\n", p)

>            free(p);

That might free something unallocated.

>        This  feature  is not available if the program is compiled with
>        cc -std=cc99 or cc -D_ISOC99_SOURCE (unless _GNU_SOURCE is also
>        specified),  in  which case the a is interpreted as a specifier
>        for floating point numbers (see above).

Maybe "gcc" instead of "cc" as I don't expect all the cc
implementations to have such a -std option.

>        Since version 2.7, glibc also provides the m modifier  for  the
>        same purpose as the a modifier.  The m modifier has the follow-
>        ing advantages:
> 
>        * It may also be applied to  %c  conversion  specifiers  (e.g.,
>          %3mc).
> 
>        * It  avoids  ambiguity  with  respect to the %a floating-point
>          conversion specifier (and is unaffected by cc -std=99 etc.)
> 
>        * It is specified in the upcoming revision of the POSIX.1 stan-
>          dard.

Thanks for that, I hadn't thought of checking the draft.

I can see the draft makes it clear that you don't need to free
the buffer if scanf fails. I think it should be mentionned in
the man page as well as it seems to also be the case for %a.

So:

errno = 0;
n = scanf(..., &p);
if (n == 1) {
  printf("OK: %s\n", p);
  free(p);
} else if (errno != 0) {
  perror("scanf");
}
else {
  fprintf(stderr, "expected letters, not \"%s\"\n", ...);
}

-- 
Stéphane



--
To UNSUBSCRIBE, email to [EMAIL PROTECTED]
with a subject of "unsubscribe". Trouble? Contact [EMAIL PROTECTED]

Reply via email to