Validating a string with sscanf

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Richard

    Validating a string with sscanf

    I'm validating a date and time string which must be EXACTLY of the format

    yy-mm-dd hh:mm:ss

    and extracting the six numeric values using sscanf.

    I'm using the format string "%2u-%2u-%2u %2u:%2u:%2u" which works, but it
    allows each numeric field to be either 1 or 2 digits in length. Also the man
    page for sscanf says that preceeding white space before a numeric is
    ignored.

    But I need the input string to be EXACTLY of the above format (each numeric
    is exactly 2 digits long and there is no white space) otherwise the input
    string should be rejected.

    What is the best way of validating the input string against an EXACT format
    string and exctracting the six numeric values, or must I manually examine
    every character of the input string?

  • Sean G. McLaughlin

    #2
    Re: Validating a string with sscanf

    Richard wrote:
    I'm validating a date and time string which must be EXACTLY of the format
    >
    yy-mm-dd hh:mm:ss
    [snip]
    What is the best way of validating the input string against an EXACT
    format string and exctracting the six numeric values, or must I manually
    examine every character of the input string?
    If you want to know the absolute best way, then you have one of three
    courses of action:

    1. Use a DSL that is suited to this task and that generates C code.
    lex/flex is quite good.

    2. Use a library that provides regexes, and validate with that. Regex
    libraries are a dime a dozen, too. For example, they are in POSIX.2
    (see 'man 3 regex' on Unix).

    3. Drop C and use a language that has (1) or (2) built-in, like Perl or Awk
    or what have you.


    These strategies have disadvantages, though. (1) means you need to learn a
    new language, (2) means you now have two problems ;-), and (3) might not be
    an option depending on your situation. At this point you'll have to look
    into finite state automata.

    Comment

    • Ben Bacarisse

      #3
      Re: Validating a string with sscanf

      "Richard" <null@null.co.u kwrites:
      I'm validating a date and time string which must be EXACTLY of the format
      >
      yy-mm-dd hh:mm:ss
      >
      and extracting the six numeric values using sscanf.
      >
      I'm using the format string "%2u-%2u-%2u %2u:%2u:%2u" which works, but
      it allows each numeric field to be either 1 or 2 digits in
      length. Also the man page for sscanf says that preceeding white space
      before a numeric is ignored.
      >
      But I need the input string to be EXACTLY of the above format (each
      numeric is exactly 2 digits long and there is no white space)
      otherwise the input string should be rejected.
      >
      What is the best way of validating the input string against an EXACT
      format string and exctracting the six numeric values, or must I
      manually examine every character of the input string?
      If all you want (at this stage) is syntactic correctness, then you
      could test that sscanf returns 6, strlen(data) == 17 and that data
      contains only one character for which isspace is true.

      --
      Ben.

      Comment

      • Richard

        #4
        Re: Validating a string with sscanf


        "Ben Bacarisse" <ben.usenet@bsb .me.ukwrote in message
        news:871w4r4dhi .fsf@bsb.me.uk. ..
        "Richard" <null@null.co.u kwrites:
        >
        >I'm validating a date and time string which must be EXACTLY of the format
        >>
        >yy-mm-dd hh:mm:ss
        >>
        >and extracting the six numeric values using sscanf.
        >>
        >I'm using the format string "%2u-%2u-%2u %2u:%2u:%2u" which works, but
        >it allows each numeric field to be either 1 or 2 digits in
        >length. Also the man page for sscanf says that preceeding white space
        >before a numeric is ignored.
        >>
        >But I need the input string to be EXACTLY of the above format (each
        >numeric is exactly 2 digits long and there is no white space)
        >otherwise the input string should be rejected.
        >>
        >What is the best way of validating the input string against an EXACT
        >format string and exctracting the six numeric values, or must I
        >manually examine every character of the input string?
        >
        If all you want (at this stage) is syntactic correctness, then you
        could test that sscanf returns 6, strlen(data) == 17 and that data
        contains only one character for which isspace is true.
        Thanks. As this is a one-off, I've ended up checking all 17 characters
        individually, with isdigit being used for each character position where a
        numeric is required, and then calling sscanf to decode it.

        Comment

        • CBFalconer

          #5
          Re: Validating a string with sscanf

          Richard wrote:
          >
          I'm validating a date and time string which must be EXACTLY of
          the format
          yy-mm-dd hh:mm:ss
          and extracting the six numeric values using sscanf.
          I think you should make great efforts to use ISO approved date
          forms, which means that the year field will contain 4 digits. This
          will avoid any further year 2000 flaps until 10000 AD, at which
          point neither of us will probably care.

          --
          [mail]: Chuck F (cbfalconer at maineline dot net)
          [page]: <http://cbfalconer.home .att.net>
          Try the download section.


          ** Posted from http://www.teranews.com **

          Comment

          • Jack Klein

            #6
            Re: Validating a string with sscanf

            On Sun, 27 Apr 2008 13:14:21 -0400, CBFalconer <cbfalconer@yah oo.com>
            wrote in comp.lang.c:
            Richard wrote:

            I'm validating a date and time string which must be EXACTLY of
            the format
            yy-mm-dd hh:mm:ss
            and extracting the six numeric values using sscanf.
            >
            I think you should make great efforts to use ISO approved date
            forms, which means that the year field will contain 4 digits. This
            will avoid any further year 2000 flaps until 10000 AD, at which
            point neither of us will probably care.
            Speak for yourself, I plan on being around that long.

            --
            Jack Klein
            Home: http://JK-Technology.Com
            FAQs for
            comp.lang.c http://c-faq.com/
            comp.lang.c++ http://www.parashift.com/c++-faq-lite/
            alt.comp.lang.l earn.c-c++

            Comment

            • Peter Nilsson

              #7
              Re: Validating a string with sscanf

              Richard wrote:
              I'm validating a date and time string which must be EXACTLY
              of the format
              >
              yy-mm-dd hh:mm:ss
              >
              and extracting the six numeric values using sscanf.
              >
              I'm using the format string "%2u-%2u-%2u %2u:%2u:%2u"
              which works, but it allows each numeric field to be either 1 or
              2 digits in length. Also the man page for sscanf says that
              preceeding white space before a numeric is ignored.
              >
              But I need the input string to be EXACTLY of the above
              format (each numeric is exactly 2 digits long and there
              is no white space) otherwise the input string should be
              rejected.
              >
              What is the best way of validating the input string against
              an EXACT format string and exctracting the six numeric
              values, or must I manually examine every character of
              the input string?
              Pretty much, though you can do it with scanf...

              #include <stdio.h>

              #define DIGIT "%1[0123456789]"
              #define SPACE "%*1[ ]"

              #define FORMAT \
              DIGIT DIGIT "-" DIGIT DIGIT "-" DIGIT DIGIT \
              SPACE \
              DIGIT DIGIT ":" DIGIT DIGIT ":" DIGIT DIGIT

              #define DIGIT_PAIR_TO_I NT(X) \
              ( (X ## 1[0] - '0') * 10 + (X ## 2[0] - '0') )

              int main(int argc, char **argv)
              {
              if (argc)
              while (argv++, --argc)
              {
              char Y1[2], Y2[2];
              char M1[2], M2[2];
              char D1[2], D2[2];
              char h1[2], h2[2];
              char m1[2], m2[2];
              char s1[2], s2[2];

              int r = sscanf( *argv,
              FORMAT,
              Y1, Y2, M1, M2, D1, D2,
              h1, h2, m1, m2, s1, s2 );

              if (r == 12)
              {
              int Y = DIGIT_PAIR_TO_I NT(Y);
              int M = DIGIT_PAIR_TO_I NT(M);
              int D = DIGIT_PAIR_TO_I NT(D);
              int h = DIGIT_PAIR_TO_I NT(h);
              int m = DIGIT_PAIR_TO_I NT(m);
              int s = DIGIT_PAIR_TO_I NT(s);

              printf(" match:");
              printf(" %02d-%02d-%02d", Y, M, D);
              printf(" %02d:%02d:%02d" , h, m, s);
              printf("\n");
              }
              else
              printf("no match: %s\n", *argv);
              }

              return 0;
              }

              --
              Peter

              Comment

              Working...