sscanf or vsscanf : want to scan a list of integers in c

Discussion in 'C Programming' started by smshahriar@gmail.com, Feb 8, 2005.

  1. Guest

    Hi,

    I want to scan from the following string all the hex numbers and
    populate an array of integers:

    0x27 0x00
    0x30 0x00
    0x33 0x00
    0x36 0x00

    ....

    How can I do so? Doing sscanf with a long list of "%x %x ..... %x" will
    do it. But is there a better way such as a loop etc.

    Can someone please help.

    Thanks,

    Shake
     
    , Feb 8, 2005
    #1
    1. Advertising

  2. In article <>,
    <> wrote:
    :I want to scan from the following string all the hex numbers and
    :populate an array of integers:
    :
    :0x27 0x00
    :0x30 0x00
    :0x33 0x00
    :0x36 0x00

    That doesn't look like a string to me. A string would start with
    a double-quote, and would make explicit whether there are newline
    characters. e.g., "0x27 0x00\n0x30 0x00\n0x33 0x00" and so on.

    :How can I do so? Doing sscanf with a long list of "%x %x ..... %x" will
    :do it. But is there a better way such as a loop etc.

    strtoul() specifying a base of 16, and feeding the modified pointer
    back in as the new initial pointer value. Look carefully at the error
    conditions in the stroul() documentation -- different conditions get
    signalled different ways.

    You will have to decide what you want to do under various circumstances,
    such as if there is only one value per line instead of two, or if
    there is more than 2 values on one line, or if a string not interpretable
    as hex shows up, or if a huge number shows up...
    --
    I don't know if there's destiny,
    but there's a decision! -- Wim Wenders (WoD)
     
    Walter Roberson, Feb 8, 2005
    #2
    1. Advertising

  3. Guest

    Hi Walter,

    Thank you very much for your response. However I still am a little
    doubtful. I would like to explain in details.

    There is a plain text file with the following content consisting of hex
    values

    0xA8 0x00 0x00 0x00 0x00
    0x94 0x00 0x00 0x00 0x00
    0x00 0x00 0x00 0x00 0x00
    0x14 0x00 0x00
    0x28 0x00 0x00 0x00 0x00
    0x3C

    I am reading this file to a (char[]) buffer using f_op->read. I am
    working in linux kernel module so standard fscanf dosent work. As you
    can see that number of colums vary.

    Can I do some kind of automatic parsing that will enable me to get the
    hex values into an array of integer?

    shake



    Walter Roberson wrote:
    > In article <>,
    > <> wrote:
    > :I want to scan from the following string all the hex numbers and
    > :populate an array of integers:
    > :
    > :0x27 0x00
    > :0x30 0x00
    > :0x33 0x00
    > :0x36 0x00
    >
    > That doesn't look like a string to me. A string would start with
    > a double-quote, and would make explicit whether there are newline
    > characters. e.g., "0x27 0x00\n0x30 0x00\n0x33 0x00" and so on.
    >
    > :How can I do so? Doing sscanf with a long list of "%x %x ..... %x"

    will
    > :do it. But is there a better way such as a loop etc.
    >
    > strtoul() specifying a base of 16, and feeding the modified pointer
    > back in as the new initial pointer value. Look carefully at the error
    > conditions in the stroul() documentation -- different conditions get
    > signalled different ways.
    >
    > You will have to decide what you want to do under various

    circumstances,
    > such as if there is only one value per line instead of two, or if
    > there is more than 2 values on one line, or if a string not

    interpretable
    > as hex shows up, or if a huge number shows up...
    > --
    > I don't know if there's destiny,
    > but there's a decision! -- Wim Wenders (WoD)
     
    , Feb 8, 2005
    #3
  4. In article <>,
    <> wrote:
    :Thank you very much for your response. However I still am a little
    :doubtful. I would like to explain in details.

    :There is a plain text file with the following content consisting of hex
    :values

    :0xA8 0x00 0x00 0x00 0x00
    :0x94 0x00 0x00 0x00 0x00
    :0x00 0x00 0x00 0x00 0x00
    :0x14 0x00 0x00
    :0x28 0x00 0x00 0x00 0x00
    :0x3C

    :I am reading this file to a (char[]) buffer

    The whole file into one array?

    :using f_op->read.

    That doesn't sound like a C routine -- that sounds like a device
    driver.

    :I am
    :working in linux kernel module so standard fscanf dosent work.

    Sorry, I haven't worked in the linux kernel so I don't know what
    is or isn't available to the kernel.

    :As you
    :can see that number of colums vary.

    Is the whitespace significant? e.g., in the 4th line in your example,
    does the fact of there being only 3 columns signify anything like
    logical end of line?

    :Can I do some kind of automatic parsing that will enable me to get the
    :hex values into an array of integer?

    I don't know what you mean by "automatic parsing". What are you
    looking for -- a magic format string for sscanf() that will parse it
    all in one go? You can't do that with any standard sscanf(): sscanf
    can only return one value per explicitly named destination location,
    so if you want to be able to return into successive elements of an
    array, you would have to name all those successive elements...

    sscanf( string, "%i%i%i%i", &a[0], &a[1], &a[2], &a[3] ) and NOT
    sscanf( string, "%i%i%i%i" a ) expecting a[0] thru a[3] to be filled in.


    The subject line of your original posting referred to vsscanf(). That
    only passes one set of destination arguments in at the call itself, but
    the entire list of arguments still has to be passed in through
    a va_args construct, so either you would still have to code all the
    destinations as a list, or you would need a loop to construct a list
    with all the destination addresses [which would require you knew how
    many there were...]

    Speak of knowing how many there are: are we given a maximum number
    of values? Are we to assume that we've been passed a user-space
    buffer that is "big enough" (buffer overflow!!) or are you expecting
    the routine to do kernel-level malloc() and pass back the complete
    set of values? If you are expecting the routine to allocate all the
    memory, then you have to worry about the efficiency of expanding the
    size of the allocated string as you encounter more and more input...


    There is, by the way, no way to specify for sscanf() and kin the
    equivilent of the Fortran '(' ')' format repetition specifier --
    you can't write, for example, sscanf( string, "(%i)", a ) and expect
    it to keep plopping values into successive positions in a, reusing
    the %i format each time.


    In short... considering all these constraints, you're probably best
    off coding your own little loop. You may wish to use a small
    state machine implimentation:

    state 0: /* not in a number */
    space, tab, newline, or other whitespace: stay in state 0
    '0': transition to state 1
    EOF: done, do whatever you need to with the values and go on with life
    other: error -- what will you do now?

    state 1: /* leading 0 seen */
    'x' or 'X': transition to state 2
    EOF: Maybe record the value 0, if 0 by itself can stand in for 0x00.
    If so, after recording the 0 you are done, so go on with life
    If not, error -- what will you do now?
    space, tab, newline, or other whitespace: maybe record the value 0,
    If 0 by itself can stand in for 0x00.
    If so, after recording the 0, transition to state 0.
    If not, error -- what will you do now?
    other: error -- what will you do now?

    state 2: /* leading 0x seen */
    EOF: Maybe record the value 0, if 0x by itself can stand in for 0x00.
    If so, after recording the 0 you are done, so go on with life
    If not, error -- what will you do now?
    space, tab, newline, or other whitespace: maybe record the value 0,
    If 0x by itself can stand in for 0x00.
    If so, after recording the 0, transition to state 0.
    If not, error -- what will you do now?
    '0' - '9': save input character minus '0' into d1, then transition to
    state 3
    'A' - 'F': save ((input character minus 'A') plus 10) into d1, then
    transition to state 3
    'a' - 'f': save ((input character minus 'a') plus 10) into d1, then
    transition to state 3
    other: error -- what will you do now?

    state 3: /* 0x\d seen */
    EOF: maybe record the value d1, if 0x followed by a single hex digit
    can stand in for 0x0 followed by that digit.
    If so, after recording the value d1, you are done, so go on with life
    If not, error -- what will you do now?
    space, tab, newline, or other whitespace: maybe record the value d1, if
    0x followed by a single hex digit can stand in for 0x0 followed
    by that digit.
    If so, after recording the value d1, transition to state 0
    If not, error -- what will you do now?
    '0' - '9': set v = d1 * 16 + (input character minus '0'), then
    transition to state 4
    'A' - 'F': set v = d1 * 16 + ((input character minus 'A') plus 10),
    then transition to state 4
    'a' - 'f': set v = d1 * 16 + ((input character minus 'a') plus 10),
    then transition to state 4
    other: error -- what will you do now?

    state 4: /* 0x\d\d seen */
    EOF: record the value v, then you are done so go on with life
    space, tab, newline, or other whitespace: record the value v, then
    transition to state 0
    '0' - '9', 'a' - 'f', 'A' - 'F': error, number too long -- what will
    you do now?
    other: error -- what will you do now?
    --
    Warning: potentially contains traces of nuts.
     
    Walter Roberson, Feb 8, 2005
    #4
  5. Richard Bos Guest

    wrote:

    > There is a plain text file with the following content consisting of hex
    > values
    >
    > 0xA8 0x00 0x00 0x00 0x00
    > 0x94 0x00 0x00 0x00 0x00
    > 0x00 0x00 0x00 0x00 0x00
    > 0x14 0x00 0x00
    > 0x28 0x00 0x00 0x00 0x00
    > 0x3C
    >
    > I am reading this file to a (char[]) buffer using f_op->read. I am
    > working in linux kernel module so standard fscanf dosent work.


    In that case, you probably want specialist advice, since there may be
    more missing than just fscanf(). You can get this advice in a Linux
    programming group.

    Richard
     
    Richard Bos, Feb 8, 2005
    #5
    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. RoSsIaCrIiLoIA

    Why vsscanf() doesn't change errno for range error?

    RoSsIaCrIiLoIA, May 4, 2004, in forum: C Programming
    Replies:
    2
    Views:
    309
    RoSsIaCrIiLoIA
    May 4, 2004
  2. Ray Mitchell

    Simple vsscanf source code?

    Ray Mitchell, Nov 13, 2004, in forum: C Programming
    Replies:
    2
    Views:
    551
    Ray Mitchell
    Nov 13, 2004
  3. Ray Mitchell

    Simple vsscanf source code

    Ray Mitchell, Nov 16, 2004, in forum: C Programming
    Replies:
    7
    Views:
    607
    MarcSmith
    Nov 28, 2004
  4. Gaijinco

    vsscanf()

    Gaijinco, May 11, 2007, in forum: C++
    Replies:
    4
    Views:
    1,256
    =?ISO-8859-1?Q?Erik_Wikstr=F6m?=
    May 12, 2007
  5. Roy Smith
    Replies:
    1
    Views:
    164
    Peter Otten
    Jul 22, 2012
Loading...

Share This Page