Path: csiph.com!x330-a1.tempe.blueboxinc.net!usenet.pasdenom.info!gegeweb.42!gegeweb.eu!nntpfeed.proxad.net!proxad.net!feeder1-2.proxad.net!74.125.64.80.MISMATCH!postnews.google.com!news1.google.com!Xl.tags.giganews.com!border1.nntp.dca.giganews.com!nntp.giganews.com!local2.nntp.dca.giganews.com!nntp.earthlink.com!news.earthlink.com.POSTED!not-for-mail NNTP-Posting-Date: Tue, 31 Jan 2012 22:47:27 -0600 Message-ID: <4F28C3E1.2C41@mindspring.com> Date: Tue, 31 Jan 2012 23:47:29 -0500 From: pete Reply-To: pfiland@mindspring.com Organization: PF X-Mailer: Mozilla 3.04Gold (WinNT; I) MIME-Version: 1.0 Newsgroups: comp.lang.c Subject: Re: A very simple parser with scanf & C References: <88940b22-00a2-4d6e-81e1-51214b073a96@fe21g2000vbb.googlegroups.com> <0.7e9ca0c91e324ac14acd.20110923220028BST.87y5xfug7n.fsf@bsb.me.uk> <0.f03c4aaff4700164ddab.20110924003423BST.8762kivnnk.fsf@bsb.me.uk> <0.f62ca533fe3fac1321b9.20110924024253BST.87zkhuu34y.fsf@bsb.me.uk> <0.4c392657a43f99297620.20110924144538BST.87fwjmt5od.fsf@bsb.me.uk> <0.a5ee7a90b39e01baef80.20110924222135BST.87litdskkg.fsf@bsb.me.uk> <87d3eoy3p8.fsf@bazspaz.fatphil.org> <4F202866.5BEA@mindspring.com> Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit Lines: 104 X-Usenet-Provider: http://www.giganews.com NNTP-Posting-Host: 4.154.216.117 X-Trace: sv3-LjBpJ9+syqmhxXg1e6sFnfNwTje075sg0gk4wbndaUUPFPelwfztkDXNKfPqQfNBtbRiTUtmT8gEotV!NX66jYK0Nu9ZyTNb8fm95uPrFNYH64rPLFxjDolK2VFqs/kzHw2Qh8kZqw8YUAknCxceVt8jNU7m!0LfdkQJRgfE= X-Abuse-and-DMCA-Info: Please be sure to forward a copy of ALL headers X-Abuse-and-DMCA-Info: Otherwise we will be unable to process your complaint properly X-Postfilter: 1.3.40 X-Original-Bytes: 5444 Xref: x330-a1.tempe.blueboxinc.net comp.lang.c:16554 Tim Rentsch wrote: > > pete 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 > > 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