Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.c > #10759 > unrolled thread

A very simple parser with scanf & C

Started bypozz <pozzugno@gmail.com>
First post2011-09-23 07:03 -0700
Last post2011-09-25 14:07 +0100
Articles 19 on this page of 59 — 15 participants

Back to article view | Back to comp.lang.c


Contents

  A very simple parser with scanf & C pozz <pozzugno@gmail.com> - 2011-09-23 07:03 -0700
    Re: A very simple parser with scanf & C Nobody <nobody@nowhere.com> - 2011-09-23 18:28 +0100
    Re: A very simple parser with scanf & C Ben Bacarisse <ben.usenet@bsb.me.uk> - 2011-09-23 18:29 +0100
      Re: A very simple parser with scanf & C pozz <pozzugno@gmail.com> - 2011-09-23 23:16 +0200
        Re: A very simple parser with scanf & C Ben Bacarisse <ben.usenet@bsb.me.uk> - 2011-09-24 00:09 +0100
          Re: A very simple parser with scanf & C pozz <pozzugno@gmail.com> - 2011-09-24 09:32 +0200
    Re: A very simple parser with scanf & C "BartC" <bc@freeuk.com> - 2011-09-23 21:24 +0100
      Re: A very simple parser with scanf & C Ben Bacarisse <ben.usenet@bsb.me.uk> - 2011-09-23 22:00 +0100
        Re: A very simple parser with scanf & C "BartC" <bc@freeuk.com> - 2011-09-24 00:04 +0100
          Re: A very simple parser with scanf & C Ben Bacarisse <ben.usenet@bsb.me.uk> - 2011-09-24 00:34 +0100
            Re: A very simple parser with scanf & C "BartC" <bc@freeuk.com> - 2011-09-24 01:00 +0100
              Re: A very simple parser with scanf & C Ben Bacarisse <ben.usenet@bsb.me.uk> - 2011-09-24 02:42 +0100
                Re: A very simple parser with scanf & C "BartC" <bc@freeuk.com> - 2011-09-24 12:13 +0100
                  Re: A very simple parser with scanf & C "BartC" <bc@freeuk.com> - 2011-09-24 12:25 +0100
                    Re: A very simple parser with scanf & C Ben Bacarisse <ben.usenet@bsb.me.uk> - 2011-09-24 15:05 +0100
                  Re: A very simple parser with scanf & C Ben Bacarisse <ben.usenet@bsb.me.uk> - 2011-09-24 14:45 +0100
                    Re: A very simple parser with scanf & C "BartC" <bc@freeuk.com> - 2011-09-24 17:45 +0100
                      Re: A very simple parser with scanf & C Ben Bacarisse <ben.usenet@bsb.me.uk> - 2011-09-24 22:21 +0100
                        Re: A very simple parser with scanf & C "BartC" <bc@freeuk.com> - 2011-09-25 00:52 +0100
                          Re: A very simple parser with scanf & C Ben Bacarisse <ben.usenet@bsb.me.uk> - 2011-09-25 01:54 +0100
                            Re: A very simple parser with scanf & C "BartC" <bc@freeuk.com> - 2011-09-25 02:51 +0100
                              Re: A very simple parser with scanf & C Ben Bacarisse <ben.usenet@bsb.me.uk> - 2011-09-25 12:22 +0100
                          Re: A very simple parser with scanf & C Gene <gene.ressler@gmail.com> - 2011-09-25 01:35 -0700
                            Re: A very simple parser with scanf & C pete <pfiland@mindspring.com> - 2011-09-25 08:41 -0400
                              Re: A very simple parser with scanf & C Gene <gene.ressler@gmail.com> - 2011-09-25 11:23 -0700
                          Re: A very simple parser with scanf & C Phil Carmody <thefatphil_demunged@yahoo.co.uk> - 2011-09-25 19:41 +0300
                            Re: A very simple parser with scanf & C "BartC" <bc@freeuk.com> - 2011-09-25 19:45 +0100
                              Re: A very simple parser with scanf & C Keith Thompson <kst-u@mib.org> - 2011-09-25 12:10 -0700
                                Re: A very simple parser with scanf & C "BartC" <bc@freeuk.com> - 2011-09-25 20:43 +0100
                                  Re: A very simple parser with scanf & C James Kuyper <jameskuyper@verizon.net> - 2011-09-25 15:55 -0400
                                    Re: A very simple parser with scanf & C "BartC" <bc@freeuk.com> - 2011-09-26 11:07 +0100
                                      Re: A very simple parser with scanf & C Richard Damon <news.x.richarddamon@xoxy.net> - 2011-09-26 11:40 -0400
                                        Re: A very simple parser with scanf & C Keith Thompson <kst-u@mib.org> - 2011-09-26 12:22 -0700
                                          Re: A very simple parser with scanf & C pacman@kosh.dhis.org (Alan Curry) - 2011-09-26 21:19 +0000
                                            Re: A very simple parser with scanf & C Keith Thompson <kst-u@mib.org> - 2011-09-26 16:11 -0700
                                        Re: A very simple parser with scanf & C Ben Bacarisse <ben.usenet@bsb.me.uk> - 2011-09-26 23:26 +0100
                                      Re: A very simple parser with scanf & C Keith Thompson <kst-u@mib.org> - 2011-09-26 12:18 -0700
                                        Re: A very simple parser with scanf & C Phil Carmody <thefatphil_demunged@yahoo.co.uk> - 2011-09-27 02:27 +0300
                                          Re: A very simple parser with scanf & C Keith Thompson <kst-u@mib.org> - 2011-09-27 10:06 -0700
                                            Re: A very simple parser with scanf & C Ben Bacarisse <ben.usenet@bsb.me.uk> - 2011-09-27 21:10 +0100
                                      Re: A very simple parser with scanf & C Seebs <usenet-nospam@seebs.net> - 2011-09-26 22:59 +0000
                                      Re: A very simple parser with scanf & C Nick Keighley <nick_keighley_nospam@hotmail.com> - 2011-09-30 05:18 -0700
                                        Re: A very simple parser with scanf & C "BartC" <bc@freeuk.com> - 2011-09-30 17:06 +0100
                                  Re: A very simple parser with scanf & C Richard Damon <news.x.richarddamon@xoxy.net> - 2011-09-25 18:05 -0400
                                  Re: A very simple parser with scanf & C Keith Thompson <kst-u@mib.org> - 2011-09-25 15:30 -0700
                                    Re: A very simple parser with scanf & C Tim Rentsch <txr@alumni.caltech.edu> - 2012-01-24 14:01 -0800
                                      Re: A very simple parser with scanf & C pete <pfiland@mindspring.com> - 2012-01-25 11:05 -0500
                                        Re: A very simple parser with scanf & C Tim Rentsch <txr@alumni.caltech.edu> - 2012-01-31 16:01 -0800
                                          Re: A very simple parser with scanf & C pete <pfiland@mindspring.com> - 2012-01-31 23:47 -0500
                                            Re: A very simple parser with scanf & C Tim Rentsch <txr@alumni.caltech.edu> - 2012-03-08 09:21 -0800
                                              Re: A very simple parser with scanf & C pete <pfiland@mindspring.com> - 2012-03-10 15:18 -0500
                                                Re: A very simple parser with scanf & C Tim Rentsch <txr@alumni.caltech.edu> - 2012-03-13 15:49 -0700
                                                  Re: A very simple parser with scanf & C pete <pfiland@mindspring.com> - 2012-03-14 18:56 -0500
                                                    Re: A very simple parser with scanf & C Tim Rentsch <txr@alumni.caltech.edu> - 2012-03-15 17:37 -0700
                                                      Re: A very simple parser with scanf & C pete <pfiland@mindspring.com> - 2012-03-17 00:24 -0500
                                                        Re: A very simple parser with scanf & C Tim Rentsch <txr@alumni.caltech.edu> - 2012-03-21 05:21 -0700
      Re: A very simple parser with scanf & C pozz <pozzugno@gmail.com> - 2011-09-23 23:23 +0200
        Re: A very simple parser with scanf & C "BartC" <bc@freeuk.com> - 2011-09-23 23:53 +0100
    Re: A very simple parser with scanf & C Rui Maciel <rui.maciel@gmail.com> - 2011-09-25 14:07 +0100

Page 3 of 3 — ← Prev page 1 2 [3]


#10972

FromSeebs <usenet-nospam@seebs.net>
Date2011-09-26 22:59 +0000
Message-ID<slrnj81vo9.msp.usenet-nospam@guild.seebs.net>
In reply to#10942
On 2011-09-26, BartC <bc@freeuk.com> wrote:
> So, even if signed chars are not eliminated completely, why are they so
> popular, given that it is (presumably) the implementation's free choice to
> choose between signed and unsigned? (At least, the three compilers I have,
> all have char as signed.)

> Then signed chars would only ever be used by someone needing a small signed 
> integer.

I suspect consistency:  If you don't *say* signed or unsigned, for any other
normal* integer type the default is signed.  Basically, it's so that 'char'
is in the same bin as 'short', 'int', and 'long'.

-s
[*] Shut up, _Bool, we don't *care* about you.
-- 
Copyright 2011, all wrongs reversed.  Peter Seebach / usenet-nospam@seebs.net
http://www.seebs.net/log/ <-- lawsuits, religion, and funny pictures
http://en.wikipedia.org/wiki/Fair_Game_(Scientology) <-- get educated!
I am not speaking for my employer, although they do rent some of my opinions.

[toc] | [prev] | [next] | [standalone]


#11106

FromNick Keighley <nick_keighley_nospam@hotmail.com>
Date2011-09-30 05:18 -0700
Message-ID<6453021a-5b90-49d6-84dd-90a9b736ef2d@m5g2000vbe.googlegroups.com>
In reply to#10942
On Sep 26, 11:07 am, "BartC" <b...@freeuk.com> wrote:
> "James Kuyper" <jameskuy...@verizon.net> wrote in message
> news:j5o0vd$jqr$1@dont-email.me...
> > On 09/25/2011 03:43 PM, BartC wrote:


> >> Are you saying that while an implementation's char type can be signed or
> >> unsigned, it's isalpha() function assumes unsigned?
> > Keep in mind that the standard specifies that  fgetc() "obtains that
> > character as an unsigned char converted to an int", unless it returns
> > EOF to indicate an error. Those specifications make fgetc() and the
> > character classification macros good matches for each other.
>
> OK, so everywhere you look, it's clear that having unsigned char types is a
> good idea.

it hardly ever seems to matter to me

> So, even if signed chars are not eliminated completely, why are they so
> popular, given that it is (presumably) the implementation's free choice to
> choose between signed and unsigned? (At least, the three compilers I have,
> all have char as signed.)
>
> Then signed chars would only ever be used by someone needing a small signed
> integer.

[toc] | [prev] | [next] | [standalone]


#11110

From"BartC" <bc@freeuk.com>
Date2011-09-30 17:06 +0100
Message-ID<j64pf2$8ra$1@dont-email.me>
In reply to#11106
"Nick Keighley" <nick_keighley_nospam@hotmail.com> wrote in message 
news:6453021a-5b90-49d6-84dd-90a9b736ef2d@m5g2000vbe.googlegroups.com...
> On Sep 26, 11:07 am, "BartC" <b...@freeuk.com> wrote:

>> OK, so everywhere you look, it's clear that having unsigned char types is 
>> a
>> good idea.
>
> it hardly ever seems to matter to me

People keep saying that. But the problems keep appearing too.

And if it *really* doesn't matter, then why not make char unsigned by 
default? After all, nothing will break, right?

And the problem in this case was one part of a program with char codes in 
the range -128 to +127, and another part of  the program expecting char 
codes in the range 0 to +255, a conflict that requires someone (1) be aware 
of it and (2) do something about it, both being unnecessary if char codes 
were always positive. It's just a source of bugs that is completely 
unnecessary.

-- 
Bartc 

[toc] | [prev] | [next] | [standalone]


#10935

FromRichard Damon <news.x.richarddamon@xoxy.net>
Date2011-09-25 18:05 -0400
Message-ID<j5o8jb$8r7$1@dont-email.me>
In reply to#10930
On 9/25/11 3:43 PM, BartC wrote:
>
>
> "Keith Thompson" <kst-u@mib.org> wrote in message
> news:ln7h4w30c6.fsf@nuthaus.mib.org...
>> "BartC" <bc@freeuk.com> writes:
>>> "Phil Carmody" <thefatphil_demunged@yahoo.co.uk> wrote in message
>>> news:87d3eoy3p8.fsf@bazspaz.fatphil.org...
>>>> "BartC" <bc@freeuk.com> writes:
>>>>> char *lexptr; /* Points to next character of input */
>>>> ...
>>>>> while (isalpha(*lexptr));
>>>>
>>>> Bang!
>>>
>>> What's the problem?
>>
>> isalpha() expects an int argument, which either is representable
>> as an unsigned char or is equal to EOF. If plain char is signed,
>> and *lexptr happens to be negative (and not equal to EOF), the
>> behavior is undefined.
>
> I still don't get it.
>
> Are you saying that while an implementation's char type can be signed or
> unsigned, it's isalpha() function assumes unsigned?
>
> Apart from being ludicrous, how are you supposed to use it then? With an
> (unsigned char) cast? Suppose the char value really is EOF?
>
> (Quite a few threads in the past about the pointlessness of having
> signed char at all, now I know it is totally crazy, when one part of the
> same implementation can't agree with another about whether chars are
> supposed to be signed or signed!)
>
> Anyway I only used isalpha() because with my usual >=A and <=Z tests,
> someone would have called me out on that too!
>
> (BTW if I was implementing isalpha(), after checking for EOF, any
> negative char values would just be converted to unsigned ones; end of
> story.)
>

This is one "wart" in the language. The isxxx functions are based on the 
int returned by fgetc and family, not on array of chars. The undefined 
signness of char I suspect is based on my assumption that there was a 
machine in at least moderate use at the time that handled signed chars 
better than unsigned, maybe the "Load Byte" instruction automatically 
sign extended, so unsigned chars needed an explicit mask instruction.

One way around this problem is to define a new set of character 
functions (either as macros or inline functions) that automatically 
perform the cast. Ie something like

inline int isalphac(char c){ return isalpha((unsigned char)c);}

Not that a very common implementation of the isxxx functions is a table 
lookup/masking operation. Often isalpha(c) is something like

	table[c+1] & ALPHAFLAGS

This allows an easy change for changing locales, which might change 
which of the upper 128 characters are considered to be alpha.

[toc] | [prev] | [next] | [standalone]


#10936

FromKeith Thompson <kst-u@mib.org>
Date2011-09-25 15:30 -0700
Message-ID<ln39fk2r28.fsf@nuthaus.mib.org>
In reply to#10930
"BartC" <bc@freeuk.com> writes:
> "Keith Thompson" <kst-u@mib.org> wrote in message 
> news:ln7h4w30c6.fsf@nuthaus.mib.org...
>> "BartC" <bc@freeuk.com> writes:
>>> "Phil Carmody" <thefatphil_demunged@yahoo.co.uk> wrote in message
>>> news:87d3eoy3p8.fsf@bazspaz.fatphil.org...
>>>> "BartC" <bc@freeuk.com> writes:
>>>>> char *lexptr;        /* Points to next character of input */
>>>> ...
>>>>>     while (isalpha(*lexptr));
>>>>
>>>> Bang!
>>>
>>> What's the problem?
>>
>> isalpha() expects an int argument, which either is representable
>> as an unsigned char or is equal to EOF.  If plain char is signed,
>> and *lexptr happens to be negative (and not equal to EOF), the
>> behavior is undefined.
>
> I still don't get it.
>
> Are you saying that while an implementation's char type can be signed or 
> unsigned, it's isalpha() function assumes unsigned?

Yes.  C99 7.4p1:

    In all cases the argument is an int, the value of which shall
    be representable as an unsigned char or shall equal the value
    of the macro EOF. If the argument has any other value, the
    behavior is undefined.

> Apart from being ludicrous, how are you supposed to use it then? With an 
> (unsigned char) cast? Suppose the char value really is EOF?

Yes, an (unsigned char) cast is the correct way to use it.  You can omit
the cast if you happen to know that the argument is positive -- which
would probably have been the case when these functions were first
defined.  Note that all characters in the basic character set are
required to be non-negative -- but you can't assume that characters from
an outside source are non-negative.

An *unsigned char* value cannot be EOF, since EOF is negative.

Typically EOF is -1.  A (signed) char value of -1 should be passed as
255 (assuming CHAR_BIT==8).  The cast to unsigned char accomplishes
that.

[...]

-- 
Keith Thompson (The_Other_Keith) kst-u@mib.org  <http://www.ghoti.net/~kst>
"We must do something.  This is something.  Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"

[toc] | [prev] | [next] | [standalone]


#16131

FromTim Rentsch <txr@alumni.caltech.edu>
Date2012-01-24 14:01 -0800
Message-ID<kfn39b4g3py.fsf@x-alumni2.alumni.caltech.edu>
In reply to#10936
Keith Thompson <kst-u@mib.org> writes:

> "BartC" <bc@freeuk.com> writes:
>> "Keith Thompson" <kst-u@mib.org> wrote in message 
>> news:ln7h4w30c6.fsf@nuthaus.mib.org...
>>> "BartC" <bc@freeuk.com> writes:
>>>> "Phil Carmody" <thefatphil_demunged@yahoo.co.uk> wrote in message
>>>> news:87d3eoy3p8.fsf@bazspaz.fatphil.org...
>>>>> "BartC" <bc@freeuk.com> writes:
>>>>>> char *lexptr;        /* Points to next character of input */
>>>>> ...
>>>>>>     while (isalpha(*lexptr));
>>>>>
>>>>> Bang!
>>>>
>>>> What's the problem?
>>>
>>> isalpha() expects an int argument, which either is representable
>>> as an unsigned char or is equal to EOF.  If plain char is signed,
>>> and *lexptr happens to be negative (and not equal to EOF), the
>>> behavior is undefined.
>>
>> I still don't get it.
>>
>> Are you saying that while an implementation's char type can be signed or 
>> unsigned, it's isalpha() function assumes unsigned?
>
> Yes.  C99 7.4p1:
>
>     In all cases the argument is an int, the value of which shall
>     be representable as an unsigned char or shall equal the value
>     of the macro EOF. If the argument has any other value, the
>     behavior is undefined.
>
>> Apart from being ludicrous, how are you supposed to use it then? With an 
>> (unsigned char) cast? Suppose the char value really is EOF?
>
> Yes, an (unsigned char) cast is the correct way to use it.
> [snip incidental]

My understanding is that a cast to (unsigned char) may not
give exactly the right behavior.  In particular, if we have
a variable 'char c;' then to call a function like 'isalpha()'
we need to do

    isalpha( * (unsigned char*) &c )

rather than

    isalpha(   (unsigned char )  c )

to get exactly the same behavior as happens for getchar(), etc.

Of course, on most current machines these two methods give
the same results, but as a matter of correctness the first
form is the better one.  Right?

[toc] | [prev] | [next] | [standalone]


#16200

Frompete <pfiland@mindspring.com>
Date2012-01-25 11:05 -0500
Message-ID<4F202866.5BEA@mindspring.com>
In reply to#16131
Tim Rentsch wrote:
 
> My understanding is that a cast to (unsigned char) may not
> give exactly the right behavior.  In particular, if we have
> a variable 'char c;' then to call a function like 'isalpha()'
> we need to do
> 
>     isalpha( * (unsigned char*) &c )
> 
> rather than
> 
>     isalpha(   (unsigned char )  c )
> 
> to get exactly the same behavior as happens for getchar(), etc.
> 
> Of course, on most current machines these two methods give
> the same results, but as a matter of correctness the first
> form is the better one.  Right?


I don't think so.
If you were to output the value of (c) using fputc, 
then the return value of the function call would be
 ((int)(unsigned char)c).

Th value of (c) "converted to unsigned char" is ((unsigned char)c).

N869
4.9.7.3 The fputc function
Synopsis
         #include <stdio.h>
         int fputc(int c, FILE *stream);
Description
   The fputc function writes the character specified by c 
   (converted to an unsigned char ) ...


Also, isalpha also has to be able to work with arguments 
which may be constant expressions that don't have addresses.

Given

#define NEG_A   ('A' - 1 - (unsigned char)-1)

then isalpha ((unsigned char)NEG_A) should return nonzero

and putchar((unsigned char)NEG_A) should return ('A')

-- 
pete

[toc] | [prev] | [next] | [standalone]


#16535

FromTim Rentsch <txr@alumni.caltech.edu>
Date2012-01-31 16:01 -0800
Message-ID<kfnpqdz1kwh.fsf@x-alumni2.alumni.caltech.edu>
In reply to#16200
pete <pfiland@mindspring.com> writes:

> Tim Rentsch wrote:
>  
>> My understanding is that a cast to (unsigned char) may not
>> give exactly the right behavior.  In particular, if we have
>> a variable 'char c;' then to call a function like 'isalpha()'
>> we need to do
>> 
>>     isalpha( * (unsigned char*) &c )
>> 
>> rather than
>> 
>>     isalpha(   (unsigned char )  c )
>> 
>> to get exactly the same behavior as happens for getchar(), etc.
>> 
>> Of course, on most current machines these two methods give
>> the same results, but as a matter of correctness the first
>> form is the better one.  Right?
>
>
> I don't think so.
> If you were to output the value of (c) using fputc, 
> then the return value of the function call would be
>  ((int)(unsigned char)c).
>
> Th value of (c) "converted to unsigned char" is ((unsigned char)c).

That's right but the parameter c is of type 'int', not type
char.  Where did this 'int' value come from?  Presumably it
came from (among other places) an input function like 'fgetc()'
(see below).

> N869
> 4.9.7.3 The fputc function
> Synopsis
>          #include <stdio.h>
>          int fputc(int c, FILE *stream);
> Description
>    The fputc function writes the character specified by c 
>    (converted to an unsigned char ) ...

I no longer use N869, but looking at C99 (the wording is basically
unchanged from C90) for fgetc(), the description says fgetc() reads
the next character "as an 'unsigned char' converted to an 'int'"
(the single quotes designate C program text).  Note especially
the first word there, "as".

I take this phrase to mean the character object is read _as_ an
'unsigned char' (eg, through an 'unsigned char *' pointer), rather
than being _converted_ to 'unsigned char' (eg, through a 'char *'
pointer and then casting that value to 'unsigned char').

Otherwise, this sentence would have said it reads the next
character "as a 'char' converted to an 'unsigned char' converted
to an 'int'.  But it doesn't say that.

Presumably the "ctype.h" functions are meant to work correctly
on values returned by fgetc(), etc.


> Also, isalpha also has to be able to work with arguments 
> which may be constant expressions that don't have addresses.
>
> Given
>
> #define NEG_A   ('A' - 1 - (unsigned char)-1)
>
> then isalpha ((unsigned char)NEG_A) should return nonzero
>
> and putchar((unsigned char)NEG_A) should return ('A')

That's true but irrelevant to the point under discussion -- the
expression here doesn't involve characters with negative values.
The example I gave (with a variable 'char c') was just an example
for when there is a variable present.  More generally, if you want a
function like 'isalpha()' but which takes a 'char' valued argument,
this can (and, I would argue, should) be done as follows

  #define char_isalpha(c) \
    isalpha( (int) (union {char c; unsigned char u;}){ c }.u )

to match the description of how fgetc() works.

[toc] | [prev] | [next] | [standalone]


#16554

Frompete <pfiland@mindspring.com>
Date2012-01-31 23:47 -0500
Message-ID<4F28C3E1.2C41@mindspring.com>
In reply to#16535
Tim Rentsch wrote:
> 
> pete <pfiland@mindspring.com> writes:
> 
> > Tim Rentsch wrote:
> >
> >> My understanding is that a cast to (unsigned char) may not
> >> give exactly the right behavior.  In particular, if we have
> >> a variable 'char c;' then to call a function like 'isalpha()'
> >> we need to do
> >>
> >>     isalpha( * (unsigned char*) &c )
> >>
> >> rather than
> >>
> >>     isalpha(   (unsigned char )  c )
> >>
> >> to get exactly the same behavior as happens for getchar(), etc.
> >>
> >> Of course, on most current machines these two methods give
> >> the same results, but as a matter of correctness the first
> >> form is the better one.  Right?
> >
> >
> > I don't think so.
> > If you were to output the value of (c) using fputc,
> > then the return value of the function call would be
> >  ((int)(unsigned char)c).
> >
> > Th value of (c) "converted to unsigned char" is ((unsigned char)c).
> 
> That's right but the parameter c is of type 'int', not type
> char.  Where did this 'int' value come from?  Presumably it
> came from (among other places) an input function like 'fgetc()'
> (see below).
> 
> > N869
> > 4.9.7.3 The fputc function
> > Synopsis
> >          #include <stdio.h>
> >          int fputc(int c, FILE *stream);
> > Description
> >    The fputc function writes the character specified by c
> >    (converted to an unsigned char ) ...
> 
> I no longer use N869, but looking at C99 (the wording is basically
> unchanged from C90) for fgetc(), the description says fgetc() reads
> the next character "as an 'unsigned char' converted to an 'int'"
> (the single quotes designate C program text).  Note especially
> the first word there, "as".
> 
> I take this phrase to mean the character object is read _as_ an
> 'unsigned char' (eg, through an 'unsigned char *' pointer), rather
> than being _converted_ to 'unsigned char' (eg, through a 'char *'
> pointer and then casting that value to 'unsigned char').
> 
> Otherwise, this sentence would have said it reads the next
> character "as a 'char' converted to an 'unsigned char' converted
> to an 'int'.  But it doesn't say that.
> 
> Presumably the "ctype.h" functions are meant to work correctly
> on values returned by fgetc(), etc.
> 
> > Also, isalpha also has to be able to work with arguments
> > which may be constant expressions that don't have addresses.
> >
> > Given
> >
> > #define NEG_A   ('A' - 1 - (unsigned char)-1)
> >
> > then isalpha ((unsigned char)NEG_A) should return nonzero
> >
> > and putchar((unsigned char)NEG_A) should return ('A')
> 
> That's true but irrelevant to the point under discussion -- the
> expression here doesn't involve characters with negative values.
> The example I gave (with a variable 'char c') was just an example
> for when there is a variable present.  More generally, if you want a
> function like 'isalpha()' but which takes a 'char' valued argument,
> this can (and, I would argue, should) be done as follows
> 
>   #define char_isalpha(c) \
>     isalpha( (int) (union {char c; unsigned char u;}){ c }.u )
> 
> to match the description of how fgetc() works.

If you're going to say for {char c;}

>>     isalpha( * (unsigned char*) &c )
>> 
>> rather than
>> 
>>     isalpha(   (unsigned char )  c )

then I think we should consider a case where 
    ( * (unsigned char*) &c )
is different from
    (   (unsigned char )  c )
and the only case I can think of, 
is where (c) is signed, negative and not twos complement.


-- 
pete

[toc] | [prev] | [next] | [standalone]


#18330

FromTim Rentsch <txr@alumni.caltech.edu>
Date2012-03-08 09:21 -0800
Message-ID<kfnk42vt3d7.fsf@x-alumni2.alumni.caltech.edu>
In reply to#16554
pete <pfiland@mindspring.com> writes:

> Tim Rentsch wrote:
>> 
>> pete <pfiland@mindspring.com> writes:
>> 
>> > Tim Rentsch wrote:
>> >
>> >> [snip]
>
> If you're going to say for {char c;}
>
>>>     isalpha( * (unsigned char*) &c )
>>> 
>>> rather than
>>> 
>>>     isalpha(   (unsigned char )  c )
>
> then I think we should consider a case where 
>     ( * (unsigned char*) &c )
> is different from
>     (   (unsigned char )  c )
> and the only case I can think of, 
> is where (c) is signed, negative and not twos complement.

Right (ignoring padding bits in char, which no sane
implementation has), although actually there is one other
case, namely a two's complement trap representation.  Not
very likely perhaps but it is allowed, so for the sake of
completeness I think it should be mentioned.  (And now it
has been...)

[toc] | [prev] | [next] | [standalone]


#18471

Frompete <pfiland@mindspring.com>
Date2012-03-10 15:18 -0500
Message-ID<4F5BB70E.84B@mindspring.com>
In reply to#18330
Tim Rentsch wrote:
> 
> pete <pfiland@mindspring.com> writes:
> 
> > Tim Rentsch wrote:
> >>
> >> pete <pfiland@mindspring.com> writes:
> >>
> >> > Tim Rentsch wrote:
> >> >
> >> >> [snip]
> >
> > If you're going to say for {char c;}
> >
> >>>     isalpha( * (unsigned char*) &c )
> >>>
> >>> rather than
> >>>
> >>>     isalpha(   (unsigned char )  c )
> >
> > then I think we should consider a case where
> >     ( * (unsigned char*) &c )
> > is different from
> >     (   (unsigned char )  c )
> > and the only case I can think of,
> > is where (c) is signed, negative and not twos complement.
> 
> Right (ignoring padding bits in char, which no sane
> implementation has), although actually there is one other
> case, namely a two's complement trap representation.  Not
> very likely perhaps but it is allowed, so for the sake of
> completeness I think it should be mentioned.  (And now it
> has been...)

Considering that file operations are at the root of this thread:

If char is signed, and char c is assigned a value of (-1), as in
    char c;
    c = -1;

and if (c) is written to a file using fputc,
then the value written into the file will be ((unsigned char)-1).

If that same byte is read back from the same file using fgetc,
then the value returned by fgetc will be
((int)(unsigned char)-1)
which is equal to ((unsigned char)c)
regardless of the representation of negative integers.

The return value of fgetc will be unequal to 
( * (unsigned char*) &c )
when negative integers are either sign and magnitude
or one's complement.

-- 
pete

[toc] | [prev] | [next] | [standalone]


#18722

FromTim Rentsch <txr@alumni.caltech.edu>
Date2012-03-13 15:49 -0700
Message-ID<kfnobs0m7zy.fsf@x-alumni2.alumni.caltech.edu>
In reply to#18471
pete <pfiland@mindspring.com> writes:

> Tim Rentsch wrote:
>> 
>> pete <pfiland@mindspring.com> writes:
>> 
>> > Tim Rentsch wrote:
>> >>
>> >> pete <pfiland@mindspring.com> writes:
>> >>
>> >> > Tim Rentsch wrote:
>> >> >
>> >> >> [snip]
>> >
>> > If you're going to say for {char c;}
>> >
>> >>>     isalpha( * (unsigned char*) &c )
>> >>>
>> >>> rather than
>> >>>
>> >>>     isalpha(   (unsigned char )  c )
>> >
>> > then I think we should consider a case where
>> >     ( * (unsigned char*) &c )
>> > is different from
>> >     (   (unsigned char )  c )
>> > and the only case I can think of,
>> > is where (c) is signed, negative and not twos complement.
>> 
>> Right (ignoring padding bits in char, which no sane
>> implementation has), although actually there is one other
>> case, namely a two's complement trap representation.  Not
>> very likely perhaps but it is allowed, so for the sake of
>> completeness I think it should be mentioned.  (And now it
>> has been...)
>
> Considering that file operations are at the root of this thread:
>
> If char is signed, and char c is assigned a value of (-1), as in
>     char c;
>     c = -1;
>
> and if (c) is written to a file using fputc,
> then the value written into the file will be ((unsigned char)-1).
>
> If that same byte is read back from the same file using fgetc,
> then the value returned by fgetc will be
> ((int)(unsigned char)-1)
> which is equal to ((unsigned char)c)
> regardless of the representation of negative integers.
>
> The return value of fgetc will be unequal to 
> ( * (unsigned char*) &c )
> when negative integers are either sign and magnitude
> or one's complement.

That's right, of course.  Which form should be used depends
on where the bytes came from in the first place -- if they
had been written with fwrite(), for example, then the type
punning form, rather than the ordinary converting form, is
probably a better choice.  And conversely.

I suspect this is all a moot point anyway, since the values
that might be affected most likely will all have the same
characteristics vis-a-vis the <ctype.h> functions.  So I
will just say thank you for an interesting discussion.

[toc] | [prev] | [next] | [standalone]


#18788

Frompete <pfiland@mindspring.com>
Date2012-03-14 18:56 -0500
Message-ID<4F613025.6244@mindspring.com>
In reply to#18722
Tim Rentsch wrote:
> 
> pete <pfiland@mindspring.com> writes:
> 
> > Tim Rentsch wrote:
> >>
> >> pete <pfiland@mindspring.com> writes:
> >>
> >> > Tim Rentsch wrote:
> >> >>
> >> >> pete <pfiland@mindspring.com> writes:
> >> >>
> >> >> > Tim Rentsch wrote:
> >> >> >
> >> >> >> [snip]
> >> >
> >> > If you're going to say for {char c;}
> >> >
> >> >>>     isalpha( * (unsigned char*) &c )
> >> >>>
> >> >>> rather than
> >> >>>
> >> >>>     isalpha(   (unsigned char )  c )
> >> >
> >> > then I think we should consider a case where
> >> >     ( * (unsigned char*) &c )
> >> > is different from
> >> >     (   (unsigned char )  c )
> >> > and the only case I can think of,
> >> > is where (c) is signed, negative and not twos complement.
> >>
> >> Right (ignoring padding bits in char, which no sane
> >> implementation has), although actually there is one other
> >> case, namely a two's complement trap representation.  Not
> >> very likely perhaps but it is allowed, so for the sake of
> >> completeness I think it should be mentioned.  (And now it
> >> has been...)
> >
> > Considering that file operations are at the root of this thread:
> >
> > If char is signed, and char c is assigned a value of (-1), as in
> >     char c;
> >     c = -1;
> >
> > and if (c) is written to a file using fputc,
> > then the value written into the file will be ((unsigned char)-1).
> >
> > If that same byte is read back from the same file using fgetc,
> > then the value returned by fgetc will be
> > ((int)(unsigned char)-1)
> > which is equal to ((unsigned char)c)
> > regardless of the representation of negative integers.
> >
> > The return value of fgetc will be unequal to
> > ( * (unsigned char*) &c )
> > when negative integers are either sign and magnitude
> > or one's complement.
> 
> That's right, of course.  Which form should be used depends
> on where the bytes came from in the first place -- if they
> had been written with fwrite(), for example, then the type
> punning form, rather than the ordinary converting form, is
> probably a better choice.  And conversely.
> 
> I suspect this is all a moot point anyway, since the values
> that might be affected most likely will all have the same
> characteristics vis-a-vis the <ctype.h> functions.  So I
> will just say thank you for an interesting discussion.

As far as the ctype functions go,
if you want use isalpha to give you some idea of 
whether or not putchar(c) is going to output an alpha,
then isalpha((unsigned char)c) is the way to do it,
because the value returned by putchar(c)
compares equal to ((unsigned char)c).

-- 
pete

[toc] | [prev] | [next] | [standalone]


#18819

FromTim Rentsch <txr@alumni.caltech.edu>
Date2012-03-15 17:37 -0700
Message-ID<kfnbonxl6s8.fsf@x-alumni2.alumni.caltech.edu>
In reply to#18788
pete <pfiland@mindspring.com> writes:

> Tim Rentsch wrote:
>> 
>> pete <pfiland@mindspring.com> writes:
>> 
>> > Tim Rentsch wrote:
>> >>
>> >> pete <pfiland@mindspring.com> writes:
>> >>
>> >> > Tim Rentsch wrote:
>> >> >>
>> >> >> pete <pfiland@mindspring.com> writes:
>> >> >>
>> >> >> > Tim Rentsch wrote:
>> >> >> >
>> >> >> >> [snip]
>> >> >
>> >> > If you're going to say for {char c;}
>> >> >
>> >> >>>     isalpha( * (unsigned char*) &c )
>> >> >>>
>> >> >>> rather than
>> >> >>>
>> >> >>>     isalpha(   (unsigned char )  c )
>> >> >
>> >> > then I think we should consider a case where
>> >> >     ( * (unsigned char*) &c )
>> >> > is different from
>> >> >     (   (unsigned char )  c )
>> >> > and the only case I can think of,
>> >> > is where (c) is signed, negative and not twos complement.
>> >>
>> >> Right (ignoring padding bits in char, which no sane
>> >> implementation has), although actually there is one other
>> >> case, namely a two's complement trap representation.  Not
>> >> very likely perhaps but it is allowed, so for the sake of
>> >> completeness I think it should be mentioned.  (And now it
>> >> has been...)
>> >
>> > Considering that file operations are at the root of this thread:
>> >
>> > If char is signed, and char c is assigned a value of (-1), as in
>> >     char c;
>> >     c = -1;
>> >
>> > and if (c) is written to a file using fputc,
>> > then the value written into the file will be ((unsigned char)-1).
>> >
>> > If that same byte is read back from the same file using fgetc,
>> > then the value returned by fgetc will be
>> > ((int)(unsigned char)-1)
>> > which is equal to ((unsigned char)c)
>> > regardless of the representation of negative integers.
>> >
>> > The return value of fgetc will be unequal to
>> > ( * (unsigned char*) &c )
>> > when negative integers are either sign and magnitude
>> > or one's complement.
>> 
>> That's right, of course.  Which form should be used depends
>> on where the bytes came from in the first place -- if they
>> had been written with fwrite(), for example, then the type
>> punning form, rather than the ordinary converting form, is
>> probably a better choice.  And conversely.
>> 
>> I suspect this is all a moot point anyway, since the values
>> that might be affected most likely will all have the same
>> characteristics vis-a-vis the <ctype.h> functions.  So I
>> will just say thank you for an interesting discussion.
>
> As far as the ctype functions go,
> if you want use isalpha to give you some idea of 
> whether or not putchar(c) is going to output an alpha,
> then isalpha((unsigned char)c) is the way to do it,
> because the value returned by putchar(c)
> compares equal to ((unsigned char)c).

I don't find this argument persuasive, because in essence it's
no more than the tautology that 'isalpha( (unsigned char) c )'
is equal to 'isalpha( (unsigned char) c )'.  It is just as true
that 'isalpha( *(unsigned char*) &c )' will be equal to
'isalpha( *(unsigned char*) &c )' (and similarly for putting
the value through the fputc()/fget() step).  That doesn't prove
anything.

However, if we look at character/string constants, there is
some support for the type-punning view.  For example, a
character constant '0xFF' is one whose unsigned char
representation has all bits set (under CHAR_BIT==8);  that is,
it has different values (when 'char' is signed) depending
on whether two's complement, ones' complement, or sign-and-
magnitude is used to represent signed integers.  The string
comparison functions in <string.h> likewise use the unsigned
char representation rather than converting to unsigned char.
So it seems more consistent, considering those aspects, that
the <ctype.h> functions are expecting an unsigned char
representation, not just a conversion to unsigned char.

And again, practically speaking, it's highly unlikely that
there will be any difference, not counting the unusual case
of char having a trap representation.

[toc] | [prev] | [next] | [standalone]


#18830

Frompete <pfiland@mindspring.com>
Date2012-03-17 00:24 -0500
Message-ID<4F642018.7584@mindspring.com>
In reply to#18819
Tim Rentsch wrote:
> 
> pete <pfiland@mindspring.com> writes:
> 
> > Tim Rentsch wrote:
> >>
> >> pete <pfiland@mindspring.com> writes:
> >>
> >> > Tim Rentsch wrote:
> >> >>
> >> >> pete <pfiland@mindspring.com> writes:
> >> >>
> >> >> > Tim Rentsch wrote:
> >> >> >>
> >> >> >> pete <pfiland@mindspring.com> writes:
> >> >> >>
> >> >> >> > Tim Rentsch wrote:
> >> >> >> >
> >> >> >> >> [snip]
> >> >> >
> >> >> > If you're going to say for {char c;}
> >> >> >
> >> >> >>>     isalpha( * (unsigned char*) &c )
> >> >> >>>
> >> >> >>> rather than
> >> >> >>>
> >> >> >>>     isalpha(   (unsigned char )  c )
> >> >> >
> >> >> > then I think we should consider a case where
> >> >> >     ( * (unsigned char*) &c )
> >> >> > is different from
> >> >> >     (   (unsigned char )  c )
> >> >> > and the only case I can think of,
> >> >> > is where (c) is signed, negative and not twos complement.
> >> >>
> >> >> Right (ignoring padding bits in char, which no sane
> >> >> implementation has), although actually there is one other
> >> >> case, namely a two's complement trap representation.  Not
> >> >> very likely perhaps but it is allowed, so for the sake of
> >> >> completeness I think it should be mentioned.  (And now it
> >> >> has been...)
> >> >
> >> > Considering that file operations are at the root of this thread:
> >> >
> >> > If char is signed, and char c is assigned a value of (-1), as in
> >> >     char c;
> >> >     c = -1;
> >> >
> >> > and if (c) is written to a file using fputc,
> >> > then the value written into the file will be ((unsigned char)-1).
> >> >
> >> > If that same byte is read back from the same file using fgetc,
> >> > then the value returned by fgetc will be
> >> > ((int)(unsigned char)-1)
> >> > which is equal to ((unsigned char)c)
> >> > regardless of the representation of negative integers.
> >> >
> >> > The return value of fgetc will be unequal to
> >> > ( * (unsigned char*) &c )
> >> > when negative integers are either sign and magnitude
> >> > or one's complement.
> >>
> >> That's right, of course.  Which form should be used depends
> >> on where the bytes came from in the first place -- if they
> >> had been written with fwrite(), for example, then the type
> >> punning form, rather than the ordinary converting form, is
> >> probably a better choice.  And conversely.
> >>
> >> I suspect this is all a moot point anyway, since the values
> >> that might be affected most likely will all have the same
> >> characteristics vis-a-vis the <ctype.h> functions.  So I
> >> will just say thank you for an interesting discussion.
> >
> > As far as the ctype functions go,
> > if you want use isalpha to give you some idea of
> > whether or not putchar(c) is going to output an alpha,
> > then isalpha((unsigned char)c) is the way to do it,
> > because the value returned by putchar(c)
> > compares equal to ((unsigned char)c).
> 
> I don't find this argument persuasive, because in essence it's
> no more than the tautology that 'isalpha( (unsigned char) c )'
> is equal to 'isalpha( (unsigned char) c )'.  It is just as true
> that 'isalpha( *(unsigned char*) &c )' will be equal to
> 'isalpha( *(unsigned char*) &c )' (and similarly for putting
> the value through the fputc()/fget() step).  That doesn't prove
> anything.


isalpha((unsigned char)c) will tell you 
if the output of putchar(c) is an alpha 
because putchar(c) is equal to putchar((unsigned char)c).


-- 
pete

[toc] | [prev] | [next] | [standalone]


#18921

FromTim Rentsch <txr@alumni.caltech.edu>
Date2012-03-21 05:21 -0700
Message-ID<kfn4ntijgb4.fsf@x-alumni2.alumni.caltech.edu>
In reply to#18830
pete <pfiland@mindspring.com> writes:

> Tim Rentsch wrote:
>> 
>> pete <pfiland@mindspring.com> writes:
>> 
>> > Tim Rentsch wrote:
>> >>
>> >> pete <pfiland@mindspring.com> writes:
>> >>
>> >> > Tim Rentsch wrote:
>> >> >>
>> >> >> pete <pfiland@mindspring.com> writes:
>> >> >>
>> >> >> > Tim Rentsch wrote:
>> >> >> >>
>> >> >> >> pete <pfiland@mindspring.com> writes:
>> >> >> >>
>> >> >> >> > Tim Rentsch wrote:
>> >> >> >> >
>> >> >> >> >> [snip]
>> >> >> >
>> >> >> > If you're going to say for {char c;}
>> >> >> >
>> >> >> >>>     isalpha( * (unsigned char*) &c )
>> >> >> >>>
>> >> >> >>> rather than
>> >> >> >>>
>> >> >> >>>     isalpha(   (unsigned char )  c )
>> >> >> >
>> >> >> > then I think we should consider a case where
>> >> >> >     ( * (unsigned char*) &c )
>> >> >> > is different from
>> >> >> >     (   (unsigned char )  c )
>> >> >> > and the only case I can think of,
>> >> >> > is where (c) is signed, negative and not twos complement.
>> >> >>
>> >> >> Right (ignoring padding bits in char, which no sane
>> >> >> implementation has), although actually there is one other
>> >> >> case, namely a two's complement trap representation.  Not
>> >> >> very likely perhaps but it is allowed, so for the sake of
>> >> >> completeness I think it should be mentioned.  (And now it
>> >> >> has been...)
>> >> >
>> >> > Considering that file operations are at the root of this thread:
>> >> >
>> >> > If char is signed, and char c is assigned a value of (-1), as in
>> >> >     char c;
>> >> >     c = -1;
>> >> >
>> >> > and if (c) is written to a file using fputc,
>> >> > then the value written into the file will be ((unsigned char)-1).
>> >> >
>> >> > If that same byte is read back from the same file using fgetc,
>> >> > then the value returned by fgetc will be
>> >> > ((int)(unsigned char)-1)
>> >> > which is equal to ((unsigned char)c)
>> >> > regardless of the representation of negative integers.
>> >> >
>> >> > The return value of fgetc will be unequal to
>> >> > ( * (unsigned char*) &c )
>> >> > when negative integers are either sign and magnitude
>> >> > or one's complement.
>> >>
>> >> That's right, of course.  Which form should be used depends
>> >> on where the bytes came from in the first place -- if they
>> >> had been written with fwrite(), for example, then the type
>> >> punning form, rather than the ordinary converting form, is
>> >> probably a better choice.  And conversely.
>> >>
>> >> I suspect this is all a moot point anyway, since the values
>> >> that might be affected most likely will all have the same
>> >> characteristics vis-a-vis the <ctype.h> functions.  So I
>> >> will just say thank you for an interesting discussion.
>> >
>> > As far as the ctype functions go,
>> > if you want use isalpha to give you some idea of
>> > whether or not putchar(c) is going to output an alpha,
>> > then isalpha((unsigned char)c) is the way to do it,
>> > because the value returned by putchar(c)
>> > compares equal to ((unsigned char)c).
>> 
>> I don't find this argument persuasive, because in essence it's
>> no more than the tautology that 'isalpha( (unsigned char) c )'
>> is equal to 'isalpha( (unsigned char) c )'.  It is just as true
>> that 'isalpha( *(unsigned char*) &c )' will be equal to
>> 'isalpha( *(unsigned char*) &c )' (and similarly for putting
>> the value through the fputc()/fget() step).  That doesn't prove
>> anything.
>
>
> isalpha((unsigned char)c) will tell you 
> if the output of putchar(c) is an alpha 
> because putchar(c) is equal to putchar((unsigned char)c).

Sorry, I misunderstood your point before.  However, my basic
point still stands - depending on circumstances, the type punning
form might be a better choice than conversion, or vice versa.  We
don't necessarily want to use 'putchar(c)' if c is a char, since
(for example) if char uses a ones complement representation then
plus zero and minus zero will both end up just being zero;  using
'putchar( *(unsigned char*)&c )' might be a better choice in such
cases.

[toc] | [prev] | [next] | [standalone]


#10812

Frompozz <pozzugno@gmail.com>
Date2011-09-23 23:23 +0200
Message-ID<j5itcg$8tf$1@nnrp.ngi.it>
In reply to#10799
Il 23/09/2011 22:24, BartC ha scritto:
> "pozz" <pozzugno@gmail.com> wrote in message
> news:88940b22-00a2-4d6e-81e1-51214b073a96@fe21g2000vbb.googlegroups.com...
>
>> What do you think about the following code? Is there a better way?
>
> It's fine for a first attempt, other than it doesn't seem to work! All
> your test cases came out as 'OK'.

Indeed all the tests should pass for correct and malformed strings, if 
the algorithm correctly works.  As you can see, in the test array I set 
idx=-1 for malformed strings.  If the parse() function correctly detects 
the malformed string, the test is classified with "OK".


>> if (!strncasecmp(ids[i], s, strlen(ids[i]))) {
>
> You're testing a string in situ, against a constant string of certain
> length.
>
> This will match a string which is longer, but has the same common
> characters (although the next stage may or may not pick up the extra
> characters).

Indeed, I created the following test with a malformed string:

   { "lockk door 1",    -1    }, /* lockk instead of lock */

The test passes so parse() correctly detects the unknown starting ID, 
even if an initial part of it matches a correct ID.

[toc] | [prev] | [next] | [standalone]


#10828

From"BartC" <bc@freeuk.com>
Date2011-09-23 23:53 +0100
Message-ID<j5j3b8$s1i$1@dont-email.me>
In reply to#10812
"pozz" <pozzugno@gmail.com> wrote in message 
news:j5itcg$8tf$1@nnrp.ngi.it...
> Il 23/09/2011 22:24, BartC ha scritto:

>> It's fine for a first attempt, other than it doesn't seem to work! All
>> your test cases came out as 'OK'.
>
> Indeed all the tests should pass for correct and malformed strings, if the 
> algorithm correctly works.  As you can see, in the test array I set idx=-1 
> for malformed strings.  If the parse() function correctly detects the 
> malformed string, the test is classified with "OK".

I get how it works now. But I used a slightly different main() function so I 
could see what was happening; see below. (I also put in some spacing; 
indentation seems to have got lost in your post.)

Now, the only error I see is that it doesn't detect a missing space between 
the ID and the rest (your spec suggested there should be at least one 
space).

int
main(void)
{
int i;

for (i = 0; i < TEST_NUM; i++) {
 int ret;
 int num;
 int id_idx;

 printf("Test %2d <%s>\t", i,test[i].s);
 ret = parse(test[i].s, &id_idx, &num);
 if (ret < 0) {
  if (test[i].idx == -1) {
   printf("OK: failed as expected\n");
  }
  else {
   printf("ERR\n");
  }
 }
 else {
  if ((test[i].idx == id_idx) && (test[i].num == num)) {
   printf("OK: passed as expected\n");
  }
  else {
   printf("ERR\n");
  }
 }
}
return 0;
}

-- 
Bartc 

[toc] | [prev] | [next] | [standalone]


#10917

FromRui Maciel <rui.maciel@gmail.com>
Date2011-09-25 14:07 +0100
Message-ID<4e7f279f$0$16758$a729d347@news.telepac.pt>
In reply to#10759
pozz wrote:

> I want to write a very simple (at least, I thought it was very simple)
> parser of a string. This string has the following format:
> - a string ID that matches one of a known list (no whitespaces
> before), case insensitive
> - one or more whitespaces (spaces, tabs, newlines...)
> - the word "door" (without quotes), case insensitive
> - an optional number of whitespaces, even zero
> - a number in the range 0..10
> - no other characters after the number
> Of course, I want to write a good parser, so avoiding any possible
> memory leak, buffer overrun, segmentation fault...
> 
> What do you think about the following code? Is there a better way? Did
> I forget something? Is it portable (I don't know about strcasecmp()
> and strncasecmp())?
<snip/> 

Developing a proper parser is a better way to handle this task.  As the 
language you want to parse is a simple one, I suggest you try to develop a 
LL parser by hand.  Besides being able to develop a bullet-proof piece of 
code, you will find it to be a very rewarding experience.


Rui Maciel

[toc] | [prev] | [standalone]


Page 3 of 3 — ← Prev page 1 2 [3]

Back to top | Article view | comp.lang.c


csiph-web