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

From: Walter Roberson (roberson_at_ibd.nrc-cnrc.gc.ca)
Date: 02/08/05


Date: 8 Feb 2005 05:53:16 GMT

In article <1107830052.171228.290890@l41g2000cwc.googlegroups.com>,
 <smshahriar@gmail.com> 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.


Relevant Pages

  • Re: [PHP] What is "white space"
    ... >>issues with there being a space, a tab, a newline, or any whitespace ... scalable system for accessing system services | ...
    (php.general)
  • Text Form Field Too Small
    ... If I click slightly to the right of that field it tries to tab to ... They would have to click directly on the single character because the ... rest of the area is now uneditable whitespace. ... When they edit this field it will either shrink the field down ...
    (microsoft.public.word.docmanagement)
  • Re: fscanf and linked list problem
    ... the final newline in the scanf directive does not mean what ... read and consume any leading whitespace, ... "characters not including semicolon". ... directives, however, cause a problem: ...
    (comp.lang.c)
  • Re: Sementation Fault reading a file
    ... actually it skips leading whitespace and then up to ... nonwhitespace characters. ... *scanf stops at that point and doesn't do the %*c which would skip the ... skips the newline. ...
    (comp.lang.fortran)
  • Another version of cleanfile/cleanpatch (Re: [PATCH 08/19] scripts: Make cleanfile/cleanpatch warn a
    ... While i'm against whitespace damaged files or patches since my very ... tab spaces tab, bust be 2 tabs ...
    (Linux-Kernel)