Odd scanf problem 
Author Message
 Odd scanf problem

Yes, I know scanf is Considered Harmful, but under proper conditions
it's very useful. However, there is one slight oddity in its behaviour
I am curious about.

I have a CSV database which I want to read in. Each record is a single
line, fields separated with commas. No problem!

        sscanf(b, "%d,%d,%d,%d"...

Some fields are strings. Again, no problem.

        sscanf(b, "%20[^,],%20[^,]"...

Unfortunately, some of the string fields are blank, giving a record which
looks like:

        1,2,foo,,bar

According to the scanf documentation (GNU info version, I don't have my
K&R handy), %[ won't match an empty string. Instead it reports a matching
error. %s, however, will read an empty string, but it uses white space to
terminate, and I'm not using white space as a terminator.

This means that I can't use scanf to read my database. At the first empty
field, it reports a matching error and my routine dies. scanf is really
the most elegant way (I can see) of doing it, apart from this one problem.

I have two questions. One; why, on earth, is there this restriction; and
two, how can I get round it. The current kludge is to persuade the program
that produces the database to output a single space instead of a blank
field, but this is narsty.

While I'm at it, here's another one. How common is the GNU extension that
adding the a flag to a %s or %[ makes it automatically allocate space for
the string? How many machines use GNU libc?

BTW, my email address doesn't work at the present (don't ask), so you'll
have to post here. [To moderator: sorry.] Also, there's no point replying
to me personally after Friday because I'll be on holiday. :)

TIA.

--
------------------- http://www.*-*-*.com/ ~dg --------------------
   If you're up against someone more intelligent than you are, do something
    totally insane and let him think himself to death.  --- Pyanfar Chanur
---------------- Sun-Earther David Daton Given of Lochcarron ------------------



Fri, 15 Jan 1999 03:00:00 GMT  
 Odd scanf problem


Quote:
>Unfortunately, some of the string fields are blank, giving a record which
>looks like:

>    1,2,foo,,bar

You could try strtok().

char *p;
char *delims[]={",\n"};

[..read in your string here...]
p=strtok( string, delims ) ;
if( p )
  printf( "First field:  %s\n", p ) ;
p=strtok( NULL, delims ) ;
if( p )
  printf( "Second field:  %s\n", p ) ;
p=strtok( NULL, delims ) ;
if( p )
  printf( "Third field:  %s\n", p ) ;
p=strtok( NULL, delims ) ;
if( p )
  printf("Fourth field:  %s\n", p ) ;

+------------------------------------------------------------------------------+
: The opinions in this message do not necessarily reflect those of my employer.:

+------------------------------------------------------------------------------+



Sat, 16 Jan 1999 03:00:00 GMT  
 Odd scanf problem



d:
d: >Unfortunately, some of the string fields are blank, giving a record which
d: >looks like:
d: >
d: > 1,2,foo,,bar
d:
d: You could try strtok().
d:
d: char *p;
d: char *delims[]={",\n"};
d:
d: [..read in your string here...]
d: p=strtok( string, delims ) ;
d: if( p )
d:   printf( "First field:  %s\n", p ) ;
d: p=strtok( NULL, delims ) ;
d: if( p )
d:   printf( "Second field:  %s\n", p ) ;
d: p=strtok( NULL, delims ) ;
d: if( p )
d:   printf( "Third field:  %s\n", p ) ;
d: p=strtok( NULL, delims ) ;
d: if( p )
d:   printf("Fourth field:  %s\n", p ) ;

strtok also doesn't correctly handle an empty field: in this case it
will incorrectly report that fourth field is present and is bar.

One way is to use the scanf family in a complicated fashion:

char fields[5][20]
for (i=0; i<5; i++) {
    if ( !scanf( i<4?"%20[^,]":"%20[^\n]", field[i]))
        field[i][0] = '\0';
    scanf(%*c);

Quote:
}

Naturally, there are other ways as well: but this is pretty simple for
me. You can trivially put in error checking by actually checking the
character that %*c is skipping over.

Cheers
Tanmoy
--

Tanmoy Bhattacharya O:T-8(MS B285)LANL,NM87545 H:#9,3000,Trinity Drive,NM87544
Others see <gopher://yaleinfo.yale.edu:7700/00/Internet-People/internet-mail>,
<http://alpha.acast.nova.edu/cgi-bin/inmgq.pl>or<ftp://csd4.csd.uwm.edu/pub/
internetwork-mail-guide>. -- <http://nqcd.lanl.gov/people/tanmoy/tanmoy.html>
fax: 1 (505) 665 3003   voice: 1 (505) 665 4733    [ Home: 1 (505) 662 5596 ]



Mon, 18 Jan 1999 03:00:00 GMT  
 Odd scanf problem

scanf() is not meant to be the only input mechanism.  If you want
to scan comma-separated input fields I suggest fgets()ing the line
into a char array then use strtok() to parse it into substrings,
or some similar approach.



Tue, 19 Jan 1999 03:00:00 GMT  
 Odd scanf problem

Quote:


>  Richard Given) writes:

> >Unfortunately, some of the string fields are blank, giving a record which
> >looks like:

> >       1,2,foo,,bar

> You could try strtok().

[clip code, blah blah blah]
strtok also has problems with empty fields on several platforms.

eg "hello,,world"

will give "hello" on the first call [ strtok( buff, "," ) ]
and "world" on the second.          [ strtok( NULL, "," ) ]
and NULL on the third

[Not just several platforms, but all functional ones. -mod]

--
Miles Davies
(my Boss probably wouldn't agree with what I just said.)



Tue, 19 Jan 1999 03:00:00 GMT  
 Odd scanf problem

Quote:

>char fields[5][20]

                  ^^^

Quote:
>for (i=0; i<5; i++) {
>    if ( !scanf( i<4?"%20[^,]":"%20[^\n]", field[i]))
>    field[i][0] = '\0';
>    scanf(%*c);
     ^^^^^^^^^^
>}

>Naturally, there are other ways as well: but this is pretty simple for
>me. You can trivially put in error checking by actually checking the
>character that %*c is skipping over.

  And inserting semicolons and quotes in the appropriate places so that the
code will compile. :-)


/*   Indeed, C++ is a bit of an oddball of a language ... given the way that *
 * it requires private parts to be visible.  This increases the strength of  *
 * coupling dramatically...                       -- Dr. Rich Artym          */



Wed, 20 Jan 1999 03:00:00 GMT  
 Odd scanf problem


: Yes, I know scanf is Considered Harmful, but under proper conditions
: it's very useful. However, there is one slight oddity in its behaviour
: I am curious about.

: I have a CSV database which I want to read in. Each record is a single
: line, fields separated with commas. No problem!

:       sscanf(b, "%d,%d,%d,%d"...

: Some fields are strings. Again, no problem.

:       sscanf(b, "%20[^,],%20[^,]"...

: Unfortunately, some of the string fields are blank, giving a record which
: looks like:

:       1,2,foo,,bar
Perhaps I am missing something but the below will work for me.
I am assuming that the line ends with a newline and that it is quite a bit
shorter than 256 characters.
int a=0,b=0;
char c[21]={0},d[21]={0},e[21]={0};
char line[256];

fgets(line,256,stdin);
if(5 != sscanf("%d%*c%d%*c%20[^,]%*c%20[^,]%*c%20[^\n]%*c",&a,&b,c,d,e))
    some fields were empty;
This is not quite bulletproof but is seems to work.

---------------------------------------------------------------------


Canada
---------------------------------------------------------------------



Wed, 20 Jan 1999 03:00:00 GMT  
 Odd scanf problem

 >

 > : Yes, I know scanf is Considered Harmful, but under proper conditions
 > : it's very useful. However, there is one slight oddity in its behaviour
 > : I am curious about.
 >
 > : I have a CSV database which I want to read in. Each record is a single
 > : line, fields separated with commas. No problem!
 >
 > :       sscanf(b, "%d,%d,%d,%d"...
 >
 > : Some fields are strings. Again, no problem.
 >
 > :       sscanf(b, "%20[^,],%20[^,]"...
 >
 > : Unfortunately, some of the string fields are blank, giving a record which
 > : looks like:
 >
 > :       1,2,foo,,bar
 > Perhaps I am missing something but the below will work for me.
 > I am assuming that the line ends with a newline and that it is quite a bit
 > shorter than 256 characters.
 > int a=0,b=0;
 > char c[21]={0},d[21]={0},e[21]={0};
 > char line[256];
 >
 > fgets(line,256,stdin);
 > if(5 != sscanf("%d%*c%d%*c%20[^,]%*c%20[^,]%*c%20[^\n]%*c",&a,&b,c,d,e))
 >     some fields were empty;
 > This is not quite bulletproof but is seems to work.
 >

Make life easy on yourself.  Skip scanf and use the free recio library.

#include <recio.h>

int a, b;
char *c=NULL, *d=NULL, *e=NULL;

rinit(rerrmsg, rwarnmsg);  /* use built-in error and warning message functions */
rsetfldch(recin, ',');     /* data values separated by commas */
rsettxtch(recin, '"');     /* text surrounded by quotes - optional */

while (rgetrec(recin)) {   /* read data from standard input */
  a = rgeti(recin);
  b = rgeti(recin);
  scpys(c, rgets(recin));  /* dynamic string copy */
  scpys(d, rgets(recin));
  scpys(e, rgets(recin));

Quote:
}

free(c);  /* free dynamic string space */
free(d);
free(e);

The recio library is available from:

http://www.simtel.net/pub/simtelnet/msdos/c/recio214.zip



Sat, 23 Jan 1999 03:00:00 GMT  
 Odd scanf problem

:  >
:  >
:  > :       1,2,foo,,bar
:  > Perhaps I am missing something but the below will work for me.
:  > I am assuming that the line ends with a newline and that it is quite a bit
:  > shorter than 256 characters.
:  > int a=0,b=0;
:  > char c[21]={0},d[21]={0},e[21]={0};
:  > char line[256];
:  >
:  > fgets(line,256,stdin);
:  > if(5 != sscanf("%d%*c%d%*c%20[^,]%*c%20[^,]%*c%20[^\n]%*c",&a,&b,c,d,e))
:  >     some fields were empty;
:  > This is not quite bulletproof but is seems to work.
:  >

: Make life easy on yourself.  Skip scanf and use the free recio library.
No thanks. Your way looks more complicated and mine works so why bother?

: #include <recio.h>

: int a, b;
: char *c=NULL, *d=NULL, *e=NULL;

: rinit(rerrmsg, rwarnmsg);  /* use built-in error and warning message functions */
: rsetfldch(recin, ',');     /* data values separated by commas */
: rsettxtch(recin, '"');     /* text surrounded by quotes - optional */

: while (rgetrec(recin)) {   /* read data from standard input */
:   a = rgeti(recin);
:   b = rgeti(recin);
:   scpys(c, rgets(recin));  /* dynamic string copy */
:   scpys(d, rgets(recin));
:   scpys(e, rgets(recin));
: }

I do love the names of your functions. They are sooooooo descriptive. I am
sure I could remember what they do. :-)
What allocates the memory for c, d, e?

--
---------------------------------------------------------------------


Canada
---------------------------------------------------------------------



Sun, 24 Jan 1999 03:00:00 GMT  
 Odd scanf problem

 >


 > :  >
 > :  >
 > :  > :       1,2,foo,,bar
 > :  > Perhaps I am missing something but the below will work for me.
 > :  > I am assuming that the line ends with a newline and that it is quite a bit
 > :  > shorter than 256 characters.
 > :  > int a=0,b=0;
 > :  > char c[21]={0},d[21]={0},e[21]={0};
 > :  > char line[256];
 > :  >
 > :  > fgets(line,256,stdin);
 > :  > if(5 != sscanf("%d%*c%d%*c%20[^,]%*c%20[^,]%*c%20[^\n]%*c",&a,&b,c,d,e))
 > :  >     some fields were empty;
 > :  > This is not quite bulletproof but is seems to work.
 > :  >
 >
 > : Make life easy on yourself.  Skip scanf and use the free recio library.
 > No thanks. Your way looks more complicated and mine works so why bother?
 >  How About:
  (1) fgets/sscanf way -
      (a) fix code if line length changes to greater than 255 characters
      (b) fix code if c changes to greater than 20 characters
      (c) fix code if d changes to greater than 20 characters
      (d) fix code if e changes to greater than 20 characters
      (e) fix code if "not quite bulletproof"
      (f) waste memory space since line seems to be about 80 characters
      (g) go blind trying to read "%d%*c%d%*c%20[^,]%*c%20[^,]%*c%20[^\n]%*c" <g>

   (2) recio way - no code changes required if any above conditions change

 > : #include <recio.h>
 >
 > : int a, b;
 > : char *c=NULL, *d=NULL, *e=NULL;
 >
 > : rinit(rerrmsg, rwarnmsg);  /* use built-in error and warning message functions */
 > : rsetfldch(recin, ',');     /* data values separated by commas */
 > : rsettxtch(recin, '"');     /* text surrounded by quotes - optional */
 >
 > : while (rgetrec(recin)) {   /* read data from standard input */
 > :   a = rgeti(recin);
 > :   b = rgeti(recin);
 > :   scpys(c, rgets(recin));  /* dynamic string copy */
 > :   scpys(d, rgets(recin));
 > :   scpys(e, rgets(recin));
 > : }
 >
 > I do love the names of your functions. They are sooooooo descriptive. I am
 > sure I could remember what they do. :-)

  You remembered fgets and sscanf <g>

 > What allocates the memory for c, d, e?

  The scpys function.



Mon, 25 Jan 1999 03:00:00 GMT  
 Odd scanf problem



:  > :  > :       1,2,foo,,bar
:  > :  > Perhaps I am missing something but the below will work for me.
:  > :  > I am assuming that the line ends with a newline and that it is quite a bit
:  > :  > shorter than 256 characters.
:  > :  > int a=0,b=0;
:  > :  > char c[21]={0},d[21]={0},e[21]={0};
:  > :  > char line[256];
:  > :  >
:  > :  > fgets(line,256,stdin);
:  > :  > if(5 != sscanf("%d%*c%d%*c%20[^,]%*c%20[^,]%*c%20[^\n]%*c",&a,&b,c,d,e))
:  > :  >     some fields were empty;
:  > :  > This is not quite bulletproof but is seems to work.
:  > :  >
:  >
:  > : Make life easy on yourself.  Skip scanf and use the free recio library.
:  > No thanks. Your way looks more complicated and mine works so why bother?
:  >  How About:
:   (1) fgets/sscanf way -
:       (a) fix code if line length changes to greater than 255 characters
:       (b) fix code if c changes to greater than 20 characters
:       (c) fix code if d changes to greater than 20 characters
:       (d) fix code if e changes to greater than 20 characters
:       (e) fix code if "not quite bulletproof"
:       (f) waste memory space since line seems to be about 80 characters
:       (g) go blind trying to read "%d%*c%d%*c%20[^,]%*c%20[^,]%*c%20[^\n]%*c" <g>
If you cannot read the above, well, you are not a C programmer. At least
not in the sense that I would see a C programmer. I have explained the
above to newbies who just started say a month ago and they had no trouble
understanding it. I use %d for an int %*c for a character that gets read
and discarded and the scanset %20[^,] for a string delimited by a comma and
%20[^\n] for a string delimited by a newline. the delimiters are not
%included in the string.

Alrighty then. It was meant to be an example. I would never use magic
numbers as I have above. Also I would make it totally buuletproof within my
abilities. This was an example whipped up in about 2 minutes. How long did
it take you to write recio? Also any C programmer would understand what I
am doing but would have to figure out what you are doing. You still haven't
answered how the memory gets allocated to c, d, and e. Also I don't really
care about memory as it's so blody cheap that if you are worried about
wasting a few bytes well....

:    (2) recio way - no code changes required if any above conditions change

:  > : #include <recio.h>
:  >
:  > : int a, b;
:  > : char *c=NULL, *d=NULL, *e=NULL;
:  >
:  > : rinit(rerrmsg, rwarnmsg);  /* use built-in error and warning message functions */
:  > : rsetfldch(recin, ',');     /* data values separated by commas */
:  > : rsettxtch(recin, '"');     /* text surrounded by quotes - optional */
:  >
:  > : while (rgetrec(recin)) {   /* read data from standard input */
:  > :   a = rgeti(recin);
:  > :   b = rgeti(recin);
:  > :   scpys(c, rgets(recin));  /* dynamic string copy */
How does memory get allocated? You are not passing a pointer to c and you
are not returning one to it.

:  > :   scpys(d, rgets(recin));
:  > :   scpys(e, rgets(recin));
:  > : }
:  >
:  > I do love the names of your functions. They are sooooooo descriptive. I am
:  > sure I could remember what they do. :-)

:   You remembered fgets and sscanf <g>

:  > What allocates the memory for c, d, e?

:   The scpys function.

--
---------------------------------------------------------------------


Canada
---------------------------------------------------------------------



Tue, 26 Jan 1999 03:00:00 GMT  
 Odd scanf problem


Quote:





    [snip]
>  :  > : Make life easy on yourself. Skip scanf and use the free recio library.
>  :  > No thanks. Your way looks more complicated and mine works so why bother?
[more snipping]
>  You still haven't answered how the memory gets allocated to c, d, and e.
>  :  > What allocates the memory for c, d, e?
>  :   The scpys function.

I p{roba,ossi}bly shouldn't {*filter*}in _yet_ this looks like so much fun ;-)

As a fairly new programmer, I'll make an observation or two:

1. Reading this thread, I got curious. Downloaded the recio sources.

   It's copy{left,right}ed and this is in the history file:
   recio, Version 2.14, Release June 14, 1996.
   Copyright (C) 1994-1996, William Pierpoint.

2. Haven't compiled a library yet, but I started to look at a few
   of the source files and digest them.
   recio.h has this, amongst a whole slew of other useful lookin' functions:

   #define scpys(dst, src)          (_scpys(&(dst), (src)))

   The file rstr.c has this function, _scpys(), which handles the
   memory allocation, assignments, et al.
   From what I've seen, it's pretty cool && Bill should be a proud parent ;-)

3. As C Programmers, we should build on each other's work, if possible and
   'stand on the shoulders of giants' rather than constantly trying to
   reinvent the wheel. I see this three ways:
    (a) I can invest time learning the Standard library functions and
        re-write my own recio stuff as I need it, or
    (b) I can invest time learning to understand the functions Bill has
        written and use them, or
    (c) I can do both ;-)
    I think it's beneficial to opt for #3. A total newbie should take route
    (a) imho if for no other reason than that they can find lots of learning
    help with them; an intermediate or better programmer can take (c) and
    build on good work placed in the public domain (the GNU Copyright makes
    it as good as PD with protection/recognition for Bill). Then the
    programmer using the source can add to it, share those enhancements,
    and newer programmers can continue the learn/enhance/reuse cycle.

Look again at this:

Quote:
>  :  > : Make life easy on yourself. Skip scanf and use the free recio library.
>  :  > No thanks. Your way looks more complicated and mine works so why bother?

It looks complicated because it's unfamiliar. It's generic coding with lots
of error checking. I haven't the expertise to determine if it's flawless, _but_
that's not the point. The point is that the Standard library functions can
be added to over time, and these might be tools directed toward that end.
I'm not saying they are, I'm making a _philosophical_ point. The library isn't
the Bible; it's not like we can't add to it {let's see, ... Relevations, ah
Incantations ;-) }.
We all know gets() sux; yet it remains. I remember when the Standard
Library functions were unfamiliar to me; a few still are.

Recio is something to look at, something to consider.
Gabor stated ...

Quote:
>   It was meant to be an example. I would never use magic
>  numbers as I have above. Also I would make it totally bu[l]letproof
>  within my abilities.

And, so all the more reason _not_ to reinvent the wheel but rather to
look at the work that's being done by others and take the best of the
best from those who are willing to give.

My better half is waiting. There's more to say. Later ...

gary    /* the Sorcerer's Apprentice */


           -=- visit The C Programmers' Reference -=-
        http://www.*-*-*.com/ ~garyg/main_page.html



Thu, 28 Jan 1999 03:00:00 GMT  
 Odd scanf problem

: I p{roba,ossi}bly shouldn't {*filter*}in _yet_ this looks like so much fun ;-)
: As a fairly new programmer, I'll make an observation or two:
: 1. Reading this thread, I got curious. Downloaded the recio sources.
:    It's copy{left,right}ed and this is in the history file:
:    recio, Version 2.14, Release June 14, 1996.
:    Copyright (C) 1994-1996, William Pierpoint.
: 2. Haven't compiled a library yet, but I started to look at a few
:    of the source files and digest them.
:    recio.h has this, amongst a whole slew of other useful lookin' functions:
:    #define scpys(dst, src)          (_scpys(&(dst), (src)))
Now this is kind of {*filter*}, at least to me. Why is it hidden from me that
_scpys takes a pointer. I want to know about this kind of stuff. It makes
the code clear to me. I know what's going on. Also, when he posts the code
it leaves no doubt in the mind on the use of the function.

:    The file rstr.c has this function, _scpys(), which handles the
:    memory allocation, assignments, et al.
:    From what I've seen, it's pretty cool && Bill should be a proud parent ;-)

: 3. As C Programmers, we should build on each other's work, if possible and
:    'stand on the shoulders of giants' rather than constantly trying to
:    reinvent the wheel. I see this three ways:
:     (a) I can invest time learning the Standard library functions and
:         re-write my own recio stuff as I need it, or
:     (b) I can invest time learning to understand the functions Bill has
:         written and use them, or
:     (c) I can do both ;-)
:     I think it's beneficial to opt for #3. A total newbie should take route
:     (a) imho if for no other reason than that they can find lots of learning
:     help with them; an intermediate or better programmer can take (c) and
:     build on good work placed in the public domain (the GNU Copyright makes
:     it as good as PD with protection/recognition for Bill). Then the
:     programmer using the source can add to it, share those enhancements,
:     and newer programmers can continue the learn/enhance/reuse cycle.

: Look again at this:
: >  :  > : Make life easy on yourself. Skip scanf and use the free recio library.
: >  :  > No thanks. Your way looks more complicated and mine works so why bother?
: It looks complicated because it's unfamiliar. It's generic coding with lots
: of error checking. I haven't the expertise to determine if it's flawless, _but_
: that's not the point. The point is that the Standard library functions can
: be added to over time, and these might be tools directed toward that end.
: I'm not saying they are, I'm making a _philosophical_ point. The library isn't
: the Bible; it's not like we can't add to it {let's see, ... Relevations, ah
: Incantations ;-) }.
: We all know gets() sux; yet it remains. I remember when the Standard
: Library functions were unfamiliar to me; a few still are.
It's unfamiliar because he used functions that to me are undefined as I
have not seen them. Of course the standard library isn't the best. eg. why
have all the string.h functions when they are dirt easy to write while not
have functions that deal with, say, directories since there are functions
that deal with files?

: Recio is something to look at, something to consider.
: Gabor stated ...
: >   It was meant to be an example. I would never use magic
: >  numbers as I have above. Also I would make it totally bu[l]letproof
: >  within my abilities.

: And, so all the more reason _not_ to reinvent the wheel but rather to
: look at the work that's being done by others and take the best of the
: best from those who are willing to give.
OK, I agree. But, for me to use soemone else's library I would have to
first look to see if it's worth using, how to use it, etc. The question
that I answered shouldn't be answered with "use recio it's available at
wherever ... " but with an answer that a newbie can get some insight from.
BTW, where did you get recio from. You have piqued my curiosity. :-)

: My better half is waiting. There's more to say. Later ...

--
---------------------------------------------------------------------


Canada
---------------------------------------------------------------------



Sat, 30 Jan 1999 03:00:00 GMT  
 Odd scanf problem

 >




 > :  > :  > :       1,2,foo,,bar
 > :  > :  > Perhaps I am missing something but the below will work for me.
 > :  > :  > I am assuming that the line ends with a newline and that it is quite a bit
 > :  > :  > shorter than 256 characters.
 > :  > :  > int a=0,b=0;
 > :  > :  > char c[21]={0},d[21]={0},e[21]={0};
 > :  > :  > char line[256];
 > :  > :  >
 > :  > :  > fgets(line,256,stdin);
 > :  > :  > if(5 != sscanf("%d%*c%d%*c%20[^,]%*c%20[^,]%*c%20[^\n]%*c",&a,&b,c,d,e))
 > :  > :  >     some fields were empty;
 > :  > :  > This is not quite bulletproof but is seems to work.
 > :  > :  >
 > :  >
 > :  > : Make life easy on yourself.  Skip scanf and use the free recio library.
 > :  > No thanks. Your way looks more complicated and mine works so why bother?
 > :  >  How About:
 > :   (1) fgets/sscanf way -
 > :       (a) fix code if line length changes to greater than 255 characters
 > :       (b) fix code if c changes to greater than 20 characters
 > :       (c) fix code if d changes to greater than 20 characters
 > :       (d) fix code if e changes to greater than 20 characters
 > :       (e) fix code if "not quite bulletproof"
 > :       (f) waste memory space since line seems to be about 80 characters
 > :       (g) go blind trying to read "%d%*c%d%*c%20[^,]%*c%20[^,]%*c%20[^\n]%*c" <g>
 > If you cannot read the above, well, you are not a C programmer. At least
 > not in the sense that I would see a C programmer. I have explained the
 > above to newbies who just started say a month ago and they had no trouble
 > understanding it. I use %d for an int, %*c for a character that gets read
 > and discarded, and the scanset %20[^,] for a string delimited by a comma and
 > %20[^\n] for a string delimited by a newline. the delimiters are not
 > %included in the string.

Hmmm, shouldn't your sscanf line be something like

if (10 != sscanf(line, "%d%*c%d%*c%20[^,]%*c%20[^,]%*c%20[^\n]%*c",
          &a, &delim1, &b, &delim2, c, &delim3, d, &delim4, e, &delim5))

If an expert C programmer like you can make that many mistakes with sscanf,
I would think you might be interested in learning about alternative solutions.

 > Alrighty then. It was meant to be an example. I would never use magic
 > numbers as I have above. Also I would make it totally buuletproof within my
 > abilities. This was an example whipped up in about 2 minutes. How long did
 > it take you to write recio? Also any C programmer would understand what I
 > am doing but would have to figure out what you are doing. You still haven't
 > answered how the memory gets allocated to c, d, and e. Also I don't really
 > care about memory as it's so blody cheap that if you are worried about
 > wasting a few bytes well....

(1) It took me a minute or two to write my example as well.  Writing the recio
library took a little longer.

(2) Certainly if you are going to use 3rd party libraries in your code, you need
to make that fact clear in your documentation.  The recio library comes with
documentation and source, so using it could save you a lot of time.  IMHO, recio
would let your program recover from the missing data situation with a lot less
work than rolling your own solution.

(3) Speaking of recio source, take a look at the scpys source to see how memory
gets allocated.



Sun, 31 Jan 1999 03:00:00 GMT  
 Odd scanf problem

:  > :  > :  > if(5 != sscanf("%d%*c%d%*c%20[^,]%*c%20[^,]%*c%20[^\n]%*c",&a,&b,c,d,e))
:  > :  > :  >     some fields were empty;
:  > If you cannot read the above, well, you are not a C programmer. At least
:  > not in the sense that I would see a C programmer. I have explained the
:  > above to newbies who just started say a month ago and they had no trouble
:  > understanding it. I use %d for an int, %*c for a character that gets read
:  > and discarded, and the scanset %20[^,] for a string delimited by a comma and
:  > %20[^\n] for a string delimited by a newline. the delimiters are not
:  > %included in the string.

: Hmmm, shouldn't your sscanf line be something like

: if (10 != sscanf(line, "%d%*c%d%*c%20[^,]%*c%20[^,]%*c%20[^\n]%*c",
      ^^                     ^    ^         ^         ^          ^
The stars marked are assignment supression. So there are 5 variables that
are assigned. The 10 should be a 5.

:           &a, &delim1, &b, &delim2, c, &delim3, d, &delim4, e, &delim5))
                ^^^^^^^      ^^^^^^^     ^^^^^^^     ^^^^^^^     ^^^^^^^
These above are wrong and will upset sscanf. Just try it if you don't
belive me.

:  
: If an expert C programmer like you can make that many mistakes with sscanf,
: I would think you might be interested in learning about alternative solutions.

I never said I was an expert, but I did not make any mistakes in this post!
And you are wrong. * is an assignment supression, meaning that I make no
assignment of any kind to any variable.  My sscanf is correct, yours is
wrong. :-)

:  > Alrighty then. It was meant to be an example. I would never use magic
:  > numbers as I have above. Also I would make it totally buuletproof within my
:  > abilities. This was an example whipped up in about 2 minutes. How long did
:  > it take you to write recio? Also any C programmer would understand what I
:  > am doing but would have to figure out what you are doing. You still haven't
:  > answered how the memory gets allocated to c, d, and e. Also I don't really
:  > care about memory as it's so blody cheap that if you are worried about
:  > wasting a few bytes well....

: (1) It took me a minute or two to write my example as well.  Writing the recio
: library took a little longer.

: (2) Certainly if you are going to use 3rd party libraries in your code, you need
: to make that fact clear in your documentation.  The recio library comes with
: documentation and source, so using it could save you a lot of time.  IMHO, recio
: would let your program recover from the missing data situation with a lot less
: work than rolling your own solution.

: (3) Speaking of recio source, take a look at the scpys source to see how memory
: gets allocated.
It was pointed out to me by Gary. But, I don't like your use of macro's it
hides things from me and I don't like that. It looks like you are not
passing a pointer to my pointer, hence my pointer can't be modified. But in
fact your macro calls a function with a pointer. So this is hidden from me
but then you go and release memory with free that is not obvious to the
reader that it was allocated. I am not criticizing you writing recio and I
am sure it works fine, however I believe that people new to the language
should learn it thoroughly. And even you are making an obvious mistake with
sscanf above as noted. :-)

--


Canada



Sun, 31 Jan 1999 03:00:00 GMT  
 
 [ 20 post ]  Go to page: [1] [2]

 Relevant Pages 

1. ODD __gc problem

2. Very odd string problem

3. Odd ADSI Problem

4. Odd Setup Problems

5. Odd problem with System.Collections.SortedList

6. odd pointer dereference problem

7. Problem with odd loop when passing float to function

8. Problem with odd loop when passing float to function

9. odd bit field problem

10. Odd #define observation - wondering if it's causing a problem

11. Odd problem with the slider control on a semi transparent form

12. Odd String Problems

 

 
Powered by phpBB® Forum Software