slores%gables.span@umigw.miami.edu (Stanislaw L. Olejniczak) (12/11/88)
PLEASE don't flame for posting too simple a question. I think the following SHOULD work, but will not even compile: while ( (c = getchar) != EOF) chcnt++ += (c == '\n'); The purpose is to count characters in a file. Each time a newline is encountered an additional character should be counted: when the file is transferred, a newline is CR-LF combination. A person I much respect for his C knowledge told me that this would be too complex for a compiler. I would appreciate if some other people would express their opinion if the statement is legal in C. chcnt is a long int, c is a char. Many thanks! ---- Stan Olejniczak Internet: slores%gables.span@umigw.miami.edu University of Miami UUCP: {uunet!gould}!umbio!solejni Miami, Florida, USA Voice: (305)-547-6005 My opinions cannot possibly represent the views of anyone else!
wald-david@CS.YALE.EDU (david wald) (12/11/88)
In article <gables.352@umigw.miami.edu> slores%gables.span@umigw.miami.edu (Stanislaw L. Olejniczak) writes: >PLEASE don't flame for posting too simple a question. I think the following >SHOULD work, but will not even compile: > while ( (c = getchar) != EOF) > chcnt++ += (c == '\n'); Flame? Us? Never. You can't assign to a ++ expression. ============================================================================ David Wald wald-david@yale.UUCP waldave@yalevm.bitnet ============================================================================
gwyn@smoke.BRL.MIL (Doug Gwyn ) (12/11/88)
In article <gables.352@umigw.miami.edu> slores%gables.span@umigw.miami.edu (Stanislaw L. Olejniczak) writes: > while ( (c = getchar) != EOF) > chcnt++ += (c == '\n'); The main problem is that getchar is a function-like macro, requiring usage of a parenthesized argument list (containing no arguments), i.e. getchar() The next problem is that the result of chcnt++ is not a modifiable lvalue, so you cannot assign to it. Split the statement into two parts. The final problem is that you say c is a char. In that case it can never compare equal to EOF on many systems. getchar() returns an int, not a char. >... told me this would be too complex for a compiler. Well, if it weren't for the other problems, I would say that any C compiler that cannot handle expressions that complex is not worth using. Seriously!
matthew@sunpix.UUCP ( Sun NCAA) (12/12/88)
In article <gables.352@umigw.miami.edu>, slores%gables.span@umigw.miami.edu (Stanislaw L. Olejniczak) writes: > PLEASE don't flame for posting too simple a question. I think the following > SHOULD work, but will not even compile: > while ( (c = getchar) != EOF) > chcnt++ += (c == '\n'); > The purpose is to count characters in a file. Each time a newline is > encountered an additional character should be counted: when the file is > transferred, a newline is CR-LF combination. I'm not sure about the validity of the construct 'chcnt++ += (c == '\n');', but I'd write your program scrap as: while ( (c = getchar) != EOF) { if (c == '\n') chcnt++; chcnt++; } (Before closing, there is one logic flaw in your scrap of code. '(c == '\n')' does not have to evaluate to an integer 1. It must only be a non-zero value if true.) -- Matthew Lee Stier (919) 469-8300| Sun Microsystems --- RTP, NC 27560| "Wisconsin Escapee" uucp: {sun, rti}!sunpix!matthew |
ok@quintus.uucp (Richard A. O'Keefe) (12/12/88)
In article <gables.352@umigw.miami.edu> slores%gables.span@umigw.miami.edu (Stanislaw L. Olejniczak) writes: > while ( (c = getchar) != EOF) > chcnt++ += (c == '\n'); No way is this too complex for a compiler. It is just plain illegal. chcnt is a 'long' _variable_ (L-value), but chcnt++ is a 'long' _number_ (R-value). The first time round, chcnt would be 0, then chcnt++ increments chcnt to 1 and evaluates to 0. What would "0 += (c == '\n') mean? Try chcnt++, chcnt += c=='\n'; Better still would be to use a for loop: for (chcnt = 0; (c = getchar()) != EOF; chcnt++) { if (c == '\n') chcnt++; } or for (chcnt = 0; (c = getchar()) != EOF; chcnt += c == '\n' ? 2 : 1) ; (Was that really (c = getchar), or was it (c = getchar())? If the former, that's wrong too.)
hls@rwthbs.UUCP (H.L. Stahl) (12/12/88)
In article <gables.352@umigw.miami.edu> slores%gables.span@umigw.miami.edu (Stanislaw L. Olejniczak) writes: >PLEASE don't flame for posting too simple a question. I think the following >SHOULD work, but will not even compile: > while ( (c = getchar) != EOF) > chcnt++ += (c == '\n'); >... this would be too complex for a compiler. ... The answer is quite simple: "+=" is an assignment operator, on it's left side are only "lvalue"s allowed. But "chcnt++" is an expression with the result "1 + previous_value(chcnt)", and you cannot assign anything to an expression, even in C ... I hope this helps! Hans-Ludwig Stahl
gwyn@smoke.BRL.MIL (Doug Gwyn ) (12/13/88)
In article <349@greens.UUCP> matthew@sunpix.UUCP ( Sun NCAA) writes:
-(Before closing, there is one logic flaw in your scrap of code. '(c == '\n')'
-does not have to evaluate to an integer 1. It must only be a non-zero value if
-true.)
False. Relational expressions produce integer result 0 or 1, only.
rkl1@hound.UUCP (K.LAUX) (12/13/88)
In article <45370@yale-celray.yale.UUCP>, wald-david@CS.YALE.EDU (david wald) writes: > In article <gables.352@umigw.miami.edu> slores%gables.span@umigw.miami.edu (Stanislaw L. Olejniczak) writes: > >PLEASE don't flame for posting too simple a question. I think the following > >SHOULD work, but will not even compile: > > while ( (c = getchar) != EOF) > > chcnt++ += (c == '\n'); > > Flame? Us? Never. > > You can't assign to a ++ expression. > Of course you can! For example, a simple string copy function: copy_string (from, to) char *from; char *to; { while (*to++ = *from++) ; } --rkl
bamford@ihlpf.ATT.COM (Harold E. Bamford) (12/13/88)
In article <gables.352@umigw.miami.edu> slores%gables.span@umigw.miami.edu (Stanislaw L. Olejniczak) writes: >PLEASE don't flame for posting too simple a question. I think the following >SHOULD work, but will not even compile: > while ( (c = getchar) != EOF) > chcnt++ += (c == '\n'); Without a list of the error messages from the compiler, I can only guess, but the first thing that strikes me is that "getchar" should probably be written as "getchar()" as it is a macro. In my stdio.h, it is listed as: #define getchar() getc(stdin) Please, no flames about anything. Nobody cares. Harold Bamford
fransvo@htsa (Frans van Otten) (12/13/88)
In article <gables.352@umigw.miami.edu> slores%gables.span@umigw.miami.edu (Stanislaw L. Olejniczak) writes: > while ( (c = getchar) != EOF) > chcnt++ += (c == '\n'); Why is chcnt += 1 + (c == '\n') too complex for you ? Besides, it won't work. Try getchar(). -- Frans van Otten Algemene Hogeschool Amsterdam Technische en Maritieme Faculteit fransvo@htsa.uucp
ark@alice.UUCP (Andrew Koenig) (12/13/88)
In article <349@greens.UUCP>, matthew@sunpix.UUCP ( Sun NCAA) writes: > (Before closing, there is one logic flaw in your scrap of code. '(c == '\n')' > does not have to evaluate to an integer 1. It must only be a non-zero value if > true.) Nope. The value of (c == '\n') must be 1 or 0. -- --Andrew Koenig ark@europa.att.com
wald-david@CS.YALE.EDU (david wald) (12/13/88)
In article <9142@smoke.BRL.MIL> gwyn@brl.arpa (Doug Gwyn (VLD/VMB) <gwyn>) writes: >In article <gables.352@umigw.miami.edu> slores%gables.span@umigw.miami.edu (Stanislaw L. Olejniczak) writes: >> while ( (c = getchar) != EOF) >> chcnt++ += (c == '\n'); ... >The final problem is that you say c is a char. In that case it can >never compare equal to EOF on many systems. getchar() returns an int, >not a char. Doesn't the expression (c = getchar()) have type (int) regardless of the type of c? Or will c being a char really prevent this comparison? ============================================================================ David Wald wald-david@yale.UUCP waldave@yalevm.bitnet ============================================================================
wald-david@CS.YALE.EDU (david wald) (12/13/88)
In article <843@quintus.UUCP> ok@quintus.UUCP (Richard A. O'Keefe) writes: > > for (chcnt = 0; (c = getchar()) != EOF; chcnt += c == '\n' ? 2 : 1) > ; Urgh. Yes, it's not *too* unreadable, yes it's correct, but if you're going to do it like that, why bother eliminating the while loop: while ((c = getchar()) != EOF) chcnt += (c == '\n' ? 2 : 1); And, precedence rules be damned, I'd put in the parentheses. ============================================================================ David Wald wald-david@yale.UUCP waldave@yalevm.bitnet ============================================================================
ok@quintus.uucp (Richard A. O'Keefe) (12/13/88)
In article <349@greens.UUCP> matthew@sunpix.UUCP ( Sun NCAA) writes: >Before closing, there is one logic flaw in your scrap of code. '(c == '\n')' >does not have to evaluate to an integer 1. It must only be a non-zero value >if true. Wrong. All comparisons must return 0 or 1. No other result is legal in C.
moore%cdr.utah.edu@wasatch.UUCP (Tim Moore) (12/13/88)
In article <2803@hound.UUCP> rkl1@hound.UUCP (K.LAUX) writes: >In article <45370@yale-celray.yale.UUCP>, wald-david@CS.YALE.EDU (david wald) writes: >> You can't assign to a ++ expression. > Of course you can! For example, a simple string copy function: >copy_string (from, to) >char *from; >char *to; >{ > while (*to++ = *from++) > ; ^ | *to is an lvalue. Therefore you can assign to it. Now, the precedence of ++ is higher than *, so the pointer contained in (to) is incremented, but the value of *to++ is still the lvalue that *to represents. That's why the the idiom above works; you're not really assigning to a ++ expression, but to an lvalue. (Well, OK, you are, but you get the idea.) The original message contained: chcnt++ += (c == '\n'); ^ | chcnt is an lvalue here, alright, but the result of chcnt++ is the integer residing in chcnt because "When postfix++ is applied to an lvalue the result is the value of the object referred to by the lvalue"(K&R 1st ed., pg 187), which can not be assigned to. This commandment applies to the *to++ case to(!). to is an lvalue, so to++ evaluates to the pointer that resides in to, which is not an lvalue. The * operator turns the pointer into an lvalue, so assignment can proceed. -Tim Moore 4560 M.E.B. internet:moore@cs.utah.edu University of Utah ABUSENET:{ut-sally,hplabs}!utah-cs!moore Salt Lake City, UT 84112
ok@quintus.uucp (Richard A. O'Keefe) (12/13/88)
In article <45476@yale-celray.yale.UUCP> wald-david@CS.YALE.EDU (david wald) writes: >In article <843@quintus.UUCP> ok@quintus.UUCP (Richard A. O'Keefe) writes: >> for (chcnt = 0; (c = getchar()) != EOF; chcnt += c == '\n' ? 2 : 1) >> ; > >Urgh. Yes, it's not *too* unreadable, yes it's correct, but if you're >going to do it like that, why bother eliminating the while loop: But I *didn't* eliminate any "while" loop. I started again from scratch and observed that the point of the loop is to maintain chcnt, and a "for" loop was the appropriate structure. In fact, the way I would be inclined to do this is a wee bit more general: char chlen[256]; for (c = sizeof chlen; --c >= 0; ) chlen[c] = 1; chlen['\n'] = 2; for (chcnt = 0; (c = getchar()) != EOF; chcnt += chlen[c]) ; The advantage of this is that you can also add chlen['\r'] = 0; so that the same result will be obtained from a file which already has CRLF pairs as from one which has single LFs.
randy@halcdc.UUCP (randy orrison) (12/14/88)
In article <2803@hound.UUCP> rkl1@hound.UUCP (K.LAUX) writes: |> You can't assign to a ++ expression. |> | | Of course you can! For example, a simple string copy function: | | while (*to++ = *from++) ; Except that you're not assigning to a ++ expression in this example. The ++ expression is a pointer, and you're assigning to what the pointer points to. You couldn't assign to 'to++' if you wanted to. The statement still stands (as well it should): You can't assign to a ++ expression. -randy -- Randy Orrison - Control Data in the Hills of Arden randy@halcdc.uucp aka randy@{ux.acss.umn.edu, umnacvx.bitnet, cctb.mn.org, umn-cs.uucp} C: The Alpha and Omega of the Zen of Programming.
gwyn@smoke.BRL.MIL (Doug Gwyn ) (12/14/88)
In article <45472@yale-celray.yale.UUCP> wald-david@CS.YALE.EDU (david wald) writes: >Doesn't the expression (c = getchar()) have type (int) regardless of the >type of c? Or will c being a char really prevent this comparison? Doesn't matter; the important point is that wedging the int value returned by getchar() through a char knothole loses information.
guy@auspex.UUCP (Guy Harris) (12/14/88)
>Doesn't the expression (c = getchar()) have type (int) regardless of the >type of c? Or will c being a char really prevent this comparison? From K&R Second Edition (based on some particular d of the dpANS); K&R First edition says much the same thing: A7.17 Assignment Expressions ...The type of an assignment expression is that of its left operand, and the value is the value stored in the left operand after the assignment has taken place. So no, the expression has the same type as "c", which is type "char", not "int", and it has the value that was stored in "c". If "getchar()" returned EOF, and EOF is -1 (as it is on most, if not all, UNIX implementations of C) on an 8-bit-byte two's complement machine the value '\377' is stored in "c". When the comparision with EOF is done, the "char" value of the expression is converted to "int"; if "char"s are unsigned, the '\377' is converted to 255, which is definitely not equal to -1 (EOF)....
furlani@broadway.UUCP (John L. Furlani) (12/14/88)
In article <2803@hound.UUCP>, rkl1@hound.UUCP (K.LAUX) writes: > In article <45370@yale-celray.yale.UUCP>, wald-david@CS.YALE.EDU (david wald) writes: > > > > You can't assign to a ++ expression. > > > > Of course you can! For example, a simple string copy function: > > copy_string (from, to) > char *from; > char *to; > { > while (*to++ = *from++) > ; > } > Take another look. You aren't assigning anything to the ++ expression. Oops. You are assigning something to what is contained in the pointers. The *pointers* are being incremented. David Wald was correct, you can't assign to a ++ expression. Try it and watch what happens. ____________ Disclaimer: "If anyone else was responsible, it had to have been me, and myself" John L. Furlani The University of South Carolina, Columbia SC (...!uunet!ncrlnk!ncrcae!broadway!furlani)
mat@mole-end.UUCP (Mark A Terribile) (12/14/88)
> > >... I think the following SHOULD work, but will not even compile: > > >... chcnt++ += (c == '\n'); > > > > You can't assign to a ++ expression. > Of course you can! For example, a simple string copy function: > ... while (*to++ = *from++) ... Harrumph! *to++ = ... associates as ( *(to++) ) = ... If I may quote K&R (Appendix A, section 7.2): The unary * operator means _indirection_: the expression must be a pointer, and the result is an lvalue referring to ^^^^^^ the object to which the expression points. That's altogether different from ( to++ ) = ... Again quoting K&R (same section): When postfix ++ is applied to an lvalue, the result is the value of the object referred to by the lvalue. After the result is noted, the object is incremented ... Note carefully: ``the result is the value of the object referred to'' ^^^^^ That's value (or rvalue), NOT lvalue. Please excuse my dogmatic voice, but this is getting silly. (This man's opinions are his own.) From mole-end Mark Terribile -- (This man's opinions are his own.) From mole-end Mark Terribile
knudsen@ihlpl.ATT.COM (Knudsen) (12/15/88)
In article <349@greens.UUCP>, matthew@sunpix.UUCP ( Sun NCAA) writes: > (Before closing, there is one logic flaw in your scrap of code. '(c == '\n')' > does not have to evaluate to an integer 1. It must only be a non-zero value if > true.) Hey! Didn't we just finish the perennial discussion of whether C uses integer 1 for TRUE boolean expressions, or just some non-zero value? The conclusion was (and was the last time) that Boolean expressions, when required to cough up a value (as opposed to just switching control in IF statements) do indeed return exactly 1 for TRUE. In fact, Moses K. and Jesus R. said so. -- Mike Knudsen Bell Labs(AT&T) att!ihlpl!knudsen "Lawyers are like nuclear bombs and PClones. Nobody likes them, but the other guy's got one, so I better get one too."
grogers@sushi.uucp (Geoffrey Rogers) (12/17/88)
In article <gables.352@umigw.miami.edu> slores%gables.span@umigw.miami.edu (Stanislaw L. Olejniczak) writes: > chcnt++ += (c == '\n'); The above statement is not legal in C. The reason why it is not legal is because 'chcnt++' is consider to be a expression and you can not have a expression of the form "expression asignment_operator expression". Geoffrey C. Rogers CONVEX
jeremy@acadch.UUCP (Jeremy Tammik) (12/20/88)
I think you're simply missing the '()' for the getchar function/macro. Regards -Jeremy {uunet|sun}!acad!acadch!jeremy