<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE article SYSTEM "sbk:/style/dtd/article.dtd">

<article status="unfinished"
         year="2000"
         author="J&uuml;rgen Hermann"
         rcsid="$Id: snibril-scanf.xml,v 1.2 2000/02/16 00:03:56 jh Exp $">

  <copyright>
    This article is Copyright &copy; 2000 by J&uuml;rgen Hermann
    and Copyright &copy; 2000 by C-Scene. All Rights Reserved.
  </copyright>

<s1 title="scanf - The Unknown Workhorse">
  <s2 title="Introduction">
    <p>
    The <code>scanf</code> family of functions, while quite powerful, is most often
    used only by beginners (because they do not know other ways of input)
    or for simple conversions from string to other types (where the <code>strtoX()</code>
    family of functions is much more appropriate).
    </p>

    <p>Problems of <code>scanf</code> and <code>fscanf</code>, regarding keeping track of
    position...
    </p>

    <note>
      Due to the problems associated with <code>scanf</code> and <code>fscanf</code>,
      we only use <code>sscanf</code> in the following
      examples. You should do the same in your code.
    </note>
  </s2>

  <s2 title="Pitfalls to avoid">
    <p>One of the most common problem beginners have with <code>scanf</code> is the need
      to provide pointers to the variables that ultimately shall hold the parsed values.
      Since <code>scanf</code> is a function that takes a variable number of arguments,
      they are not type-checked as usual. Because of this, you can provide non-pointer arguments,
      pointers to the wrong type,
      or pointers to strings instead of just strings, and the compiler will not fetch these
      errors at compile time. If you are lucky, you get a segment violation at run-time;
      if not, you'll get other behaviour.

      !!! \% vs. %% !!!
    </p>

    <note>
      Some compilers (notably, gcc) support type-checking for literal format strings by
      parsing the format string during compile-time and then applying the appropriate
      type checks.
    </note>

    <p>
      The following code shows those common errors and the correct code on consecutive lines:
    </p>

    <source><![CDATA[
int i;
short h;
char buf[80];
char* str = buf;

/* providing the variable instead of a pointer to it */
sscanf("%d", i);        /* wrong */
sscanf("%d", &i);       /* right */

/* providing a pointer to the wrong type (or a wrong format
   to the right pointer) */
sscanf("%d", &h);       /* wrong */
sscanf("%hd", &h);      /* right */

/* providing a pointer to a string pointer instead of the
   string pointer itself (some people think "once &amp;, always &amp;) */
sscanf("%s", &str);     /* wrong */
sscanf("%s", str);      /* right */]]></source>

    <p>
      Another common error is not to check the return type of <code>scanf</code>,
      which you <em>always</em> should do. <code>scanf</code> returns the number of
      sucessfully scanned fields, so a proper <code>scanf</code> calls looks like this:
    </p>

    <source><![CDATA[
int x, y;
if (2 == sscanf(coord_string, "%d,%d", &x, &y)) {
    plot(x, y);
} else {
    perror("bad coordinates");
}]]></source>

  </s2>

  <s2 title="Parsing">
    <p>
    </p>
    <s3 title="&quot;Trial and Error&quot; parsing">
      <p>
      </p>
    </s3>
    <s3 title="Incremental parsing">
      <p>
      </p>
    </s3>
  </s2>

  <s2 title="Using character set formats">
    <p>
    </p>
  </s2>

  <s2 title="Conclusion">
    <p>
    </p>
  </s2>

  <s2 title="References">
    <p>
      <strong>Brian W. Kernighan</strong>, <strong>Dennis M. Ritchie</strong>,
      <em>The C Programming Language</em>. <br/>
      Prentice Hall, 1988, 2nd edition, ISBN 0-13-110362-8.<br/>
    </p>
  </s2>

  <anchor name="bottom"/>
</s1>

</article>