sscanf help

Discussion in 'C Programming' started by JoeT, Aug 21, 2010.

  1. JoeT

    JoeT Guest

    Hello all...

    I have to read in formatted input records that were generated on a
    mainframe computer.
    Each record is 80-characters long and divided up into 'fields' of some
    specified length.
    A synthetic record is shown below:

    <--- userName ---------------------> 01 02 03<-- agency ------------
    > 4 01


    Problem I have is I have no idea how to write the format statement in
    a sscanf to read this record (or those like it). I can't seem to
    sscanf even the first 'field', since that has embedded blanks and %s
    won't work and %36c didn't work. So...in short, I'm stumped.

    Any assistance here would be appreciated.

    Thanks,
    Joe
     
    JoeT, Aug 21, 2010
    #1
    1. Advertising

  2. JoeT

    Seebs Guest

    On 2010-08-21, JoeT <> wrote:
    > I have to read in formatted input records that were generated on a
    > mainframe computer.
    > Each record is 80-characters long and divided up into 'fields' of some
    > specified length.
    > A synthetic record is shown below:
    >
    ><--- userName ---------------------> 01 02 03<-- agency ------------
    >> 4 01

    >
    > Problem I have is I have no idea how to write the format statement in
    > a sscanf to read this record (or those like it). I can't seem to
    > sscanf even the first 'field', since that has embedded blanks and %s
    > won't work and %36c didn't work. So...in short, I'm stumped.


    Don't use sscanf, it is the wrong tool for the job. There are few jobs
    for which sscanf is the right tool.

    Since you know the format, I'd suggest that you copy chunks of it
    out and then parse them separately; if you need to parse numbers, look
    at strtol().

    -s
    --
    Copyright 2010, all wrongs reversed. Peter Seebach /
    http://www.seebs.net/log/ <-- lawsuits, religion, and funny pictures
    http://en.wikipedia.org/wiki/Fair_Game_(Scientology) <-- get educated!
     
    Seebs, Aug 21, 2010
    #2
    1. Advertising

  3. JoeT

    Chad Guest

    On Aug 21, 11:37 am, Seebs <> wrote:
    > On 2010-08-21, JoeT <> wrote:
    >
    > > I have to read in formatted input records that were generated on a
    > > mainframe computer.
    > > Each record is 80-characters long and divided up into 'fields' of some
    > > specified length.
    > > A synthetic record is shown below:

    >
    > ><--- userName --------------------->  01  02  03<-- agency ------------
    > >>   4  01

    >
    > > Problem I have is I have no idea how to write the format statement in
    > > a sscanf to read this record (or those like it). I can't seem to
    > > sscanf even the first 'field', since that has embedded blanks and %s
    > > won't work and %36c didn't work. So...in short, I'm stumped.

    >
    > Don't use sscanf, it is the wrong tool for the job.  There are few jobs
    > for which sscanf is the right tool.
    >
    > Since you know the format, I'd suggest that you copy chunks of it
    > out and then parse them separately; if you need to parse numbers, look
    > at strtol().
    >



    I got this really ugly solution using sscanf()....

    [cdalten@localhost oakland]$ more data
    userName 01 02 03 agency 4
    01

    [cdalten@localhost oakland]$ more drunk.c
    #include <stdio.h>
    #include <stdlib.h>

    #define PATH "/home/cdalten/oakland/data"
    #define MAX_SIZE 81

    int main(void)
    {
    FILE *fp;
    int n;
    char buf[BUFSIZ], pattern[MAX_SIZE];
    char name[MAX_SIZE], data1[MAX_SIZE], data2[MAX_SIZE],
    data3[MAX_SIZE], \
    agency[MAX_SIZE], data4[MAX_SIZE], data5[MAX_SIZE];

    if ((fp = fopen(PATH, "r")) == NULL) {
    fprintf(stderr, "Can't open data file\n");
    exit(1);
    }
    sprintf(pattern, "%%%ds %%%ds %%%ds %%%ds %%%ds %%%ds %%%ds", \
    MAX_SIZE-1, MAX_SIZE-1, MAX_SIZE-1, MAX_SIZE-1, MAX_SIZE-1,
    \
    MAX_SIZE-1, MAX_SIZE-1);
    while (fgets(buf, BUFSIZ, fp) != NULL) {
    n = sscanf(buf, pattern, name, data1, data2, data3, agency, data4,
    data5);
    if(n == 7)
    printf("The line is: %s %s %s %s %s %s %s\n", \
    name, data1, data2, data3, agency, data4, data5);
    }

    fclose(fp);
    exit(0);
    }
    [cdalten@localhost oakland]$ ./drunk
    The line is: userName 01 02 03 agency 4 01
    [cdalten@localhost oakland]$
     
    Chad, Aug 21, 2010
    #3
  4. JoeT

    Chad Guest

    On Aug 21, 12:37 pm, Chad <> wrote:

    > I got this really ugly solution using sscanf()....
    >
    > [cdalten@localhost oakland]$ more data
    >     userName                     01  02  03   agency             4
    > 01
    >
    > [cdalten@localhost oakland]$ more drunk.c
    > #include <stdio.h>
    > #include <stdlib.h>
    >
    > #define PATH "/home/cdalten/oakland/data"
    > #define MAX_SIZE 81
    >
    > int main(void)
    > {
    >   FILE *fp;
    >   int n;
    >   char buf[BUFSIZ], pattern[MAX_SIZE];
    >   char name[MAX_SIZE], data1[MAX_SIZE], data2[MAX_SIZE],
    > data3[MAX_SIZE], \
    >     agency[MAX_SIZE], data4[MAX_SIZE], data5[MAX_SIZE];
    >
    >   if ((fp = fopen(PATH, "r")) == NULL) {
    >     fprintf(stderr, "Can't open data file\n");
    >     exit(1);
    >   }
    >   sprintf(pattern, "%%%ds %%%ds %%%ds %%%ds %%%ds %%%ds %%%ds", \
    >           MAX_SIZE-1, MAX_SIZE-1, MAX_SIZE-1, MAX_SIZE-1, MAX_SIZE-1,
    > \
    >           MAX_SIZE-1, MAX_SIZE-1);
    >   while (fgets(buf, BUFSIZ, fp) != NULL) {
    >     n = sscanf(buf, pattern, name, data1, data2, data3, agency, data4,
    > data5);
    >     if(n == 7)
    >       printf("The line is: %s %s %s %s %s %s %s\n", \
    >              name, data1, data2, data3, agency, data4, data5);
    >   }
    >
    >   fclose(fp);
    >   exit(0);}
    >
    > [cdalten@localhost oakland]$ ./drunk
    > The line is: userName 01 02 03 agency 4 01
    > [cdalten@localhost oakland]$


    And for whatever reasons, I seem to have on going issues with tabs vs
    spaces with my current editor.
     
    Chad, Aug 21, 2010
    #4
  5. JoeT

    Mark Guest

    "Seebs" <> wrote in message
    news:...
    >> Problem I have is I have no idea how to write the format statement in
    >> a sscanf to read this record (or those like it). I can't seem to
    >> sscanf even the first 'field', since that has embedded blanks and %s
    >> won't work and %36c didn't work. So...in short, I'm stumped.

    >
    > Don't use sscanf, it is the wrong tool for the job. There are few jobs
    > for which sscanf is the right tool.


    Could you tell what are the main cons and pros of using 'sscanf' ? Does
    your comment concern *only* sscanf, but not scanf/fscanf ?

    --
    Mark
     
    Mark, Aug 25, 2010
    #5
  6. JoeT

    Seebs Guest

    On 2010-08-24, Mark <> wrote:
    > "Seebs" <> wrote in message
    > news:...
    >>> Problem I have is I have no idea how to write the format statement in
    >>> a sscanf to read this record (or those like it). I can't seem to
    >>> sscanf even the first 'field', since that has embedded blanks and %s
    >>> won't work and %36c didn't work. So...in short, I'm stumped.


    >> Don't use sscanf, it is the wrong tool for the job. There are few jobs
    >> for which sscanf is the right tool.


    > Could you tell what are the main cons and pros of using 'sscanf' ? Does
    > your comment concern *only* sscanf, but not scanf/fscanf ?


    Actually, it's much more true of scanf/fscanf. By contrast, sscanf is
    pretty livable.

    Basically, scanf has to make too many assumptions (e.g., skipping
    whitespace automatically) to be at all functional, meaning that it is
    full of surprising behaviors and corner cases. It is nearly always
    safer to just write your own string-parsing code, or to use the str*()
    functions.

    -s
    --
    Copyright 2010, all wrongs reversed. Peter Seebach /
    http://www.seebs.net/log/ <-- lawsuits, religion, and funny pictures
    http://en.wikipedia.org/wiki/Fair_Game_(Scientology) <-- get educated!
     
    Seebs, Aug 25, 2010
    #6
  7. On 21 Aug, 20:40, Chad <> wrote:

    > And for whatever reasons, I seem to have on going issues with tabs vs
    > spaces with my current editor.


    configure your editor so it replaces tabs with spaces
     
    Nick Keighley, Aug 25, 2010
    #7
  8. On Sat, 21 Aug 2010 11:35:06 -0700 (PDT), JoeT <>
    wrote:

    > I have to read in formatted input records that were generated on a
    > mainframe computer.
    > Each record is 80-characters long and divided up into 'fields' of some
    > specified length.
    > A synthetic record is shown below:
    >
    > <--- userName ---------------------> 01 02 03<-- agency ------------
    > > 4 01

    >
    > Problem I have is I have no idea how to write the format statement in
    > a sscanf to read this record (or those like it). I can't seem to
    > sscanf even the first 'field', since that has embedded blanks and %s
    > won't work and %36c didn't work. So...in short, I'm stumped.
    >

    Yes, %s won't work for embedded (or leading) blanks.

    %36c should work assuming 36 is the correct length (which it looks to
    be), and you give it a buffer to store to that is (at least) 36 chars.
    Or if you want to use the result as a string in C, the buffer must be
    (at least) 1 more char and you must put a terminating null=zero byte
    there yourself, %c doesn't add it for you (as %s and %[..] do).
    (You can, and some people do, just fill the buffer with nulls first
    before putting in the data. That's a bit wasteful, but simple.)

    And assuming of course that you have the correct record in the buffer
    you're scanning from. And that does need to be null-terminated, so
    that buffer needs to be (at least) 80+1.

    There are other ways to do this, as noted, but that doesn't mean that
    sscanf is impossible or inherently wrong. If you still have this
    problem, post actual code, as small as you can make it, that
    demonstrates the problem. For example, have a buffer initialized to a
    fixed string which is an example record, and show the sscanf(s) you
    are trying to do from it, what you get, and what you expected.
     
    David Thompson, Sep 4, 2010
    #8
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Anonymous
    Replies:
    0
    Views:
    496
    Anonymous
    Oct 30, 2003
  2. Andrej Hocevar
    Replies:
    1
    Views:
    486
    Nick Austin
    Aug 18, 2003
  3. Default User

    Help with sscanf()

    Default User, Feb 28, 2005, in forum: C Programming
    Replies:
    4
    Views:
    742
    Default User
    Mar 1, 2005
  4. Artemio

    Help with sscanf() needed desperately

    Artemio, Jul 29, 2006, in forum: C Programming
    Replies:
    8
    Views:
    349
    Default User
    Jul 30, 2006
  5. BlueJ

    help to explain sscanf()

    BlueJ, Nov 5, 2007, in forum: C Programming
    Replies:
    7
    Views:
    450
    Charlie Gordon
    Nov 8, 2007
Loading...

Share This Page