ken@birtch.UUCP (Ken B) (03/21/86)
We have a 3B2/300, and I wrote this program to help debug our spooler problem (another story), why doesn't it work? It never read's an EOF from stdin, and continues to dump 'nulls' to stdout. (Note: I'm just learning 'c', so please no flames on programming style, or lack of it) All the program does is number each line it reads from stdin. --------- code follows --------- #include <stdio.h> main() { int i=1; char c; c=getchar(); if (c!=EOF) printf("%d ",i++); while (c!=EOF) { putchar(c); if (c=='\n') { c=getchar(); if (c!=EOF) printf("%d ",i++); } else c=getchar(); } putchar(EOF); } ------ end of code ------ The system is running Sys V un*x, if that helps. The program works, except that it never stops running. I am forced to interrupt it, which writes the data out, with alot of nulls on the 'last line'. Am I doing something wrong? This exact program works correctly on our Pyramid 90x, so I know its not just my program. If anyone out there has some ideas on why it doesn't ever read an EOF, I'd be very grateful to know why. Note: how I use it is: ls -la /bin | number > outputfile or ls -la /bin | number Niether method works correctly (i.e. stops executing) Thank you, Ken Brown -- uucp: ...{!glacier!oliveb,!ihnp4!trwrb} !felix!birtch!ken These ramblings are my own, and are surely not those of my employer.
steve@jplgodo.UUCP (Steve Schlaifer x3171 156/224) (03/21/86)
In article <276@birtch.UUCP>, ken@birtch.UUCP (Ken B) writes: > We have a 3B2/300, and I wrote this program to help debug our spooler problem > (another story), why doesn't it work? It never read's an EOF from stdin, > and continues to dump 'nulls' to stdout. ..................code deleted.......................... > char c; > > c=getchar(); > if (c!=EOF) ............... remaining code deleted ................. > > This exact program works correctly on our Pyramid 90x, so I know its not just > my program. The getchar function is of type int; EOF is defined in stdio to have the value -1. When you say c=getchar(); and encounter an end of file, the value -1 from getchar is converted to \377 when it is stored in c. When c is later compared to EOF, the value of c is converted to int and then the comparison is done. This is all true no matter which machine you are running on. I suspect the 3B2 uses unsigned char's and the Pyramid uses signed char's. When \377 is converted to int on the 3B2, it becomes +127; on the Pyramid, it becomes -1. Obviously, +127 is not equal to -1 so c can never be equal to EOF on the 3B2. On the Pyramid, the sign extension done when a char is converted into an int makes everything work out fine. An easy fix for this type of problem is to declare c as an int rather than a char. -- ...smeagol\ Steve Schlaifer ......wlbr->!jplgodo!steve Advance Projects Group, Jet Propulsion Labs ....group3/ 4800 Oak Grove Drive, M/S 156/204 Pasadena, California, 91109 +1 818 354 3171
jsdy@hadron.UUCP (03/22/86)
In article <276@birtch.UUCP> ken@birtch.UUCP (Ken B) writes: >We have a 3B2/300, and I wrote this program to help debug our spooler problem >(another story), why doesn't it work? It never read's an EOF from stdin, >#include <stdio.h> >main() >{ > int i=1; > char c; > c=getchar(); > if (c!=EOF) I'm not sure why this dumps NULs: are you sure they are not DELs? Anyway, I'd bet dollars to donuts (of which I have none) that the 3B2 does not sign-extend when converting from chars to ints. The return value of getchar is an int! Therefore 'c' should be an int. You see, EOF is supposed to be an int that is out-of-band for a character. Perhaps the 3B2 EOF is something with a high bit set and the low byte 0? If you want to avoid using fgets: while (fgets(bigbuf, sizeof(bigbuf), stdin) != NULL) printf("%d:\t%s", i++, bigbuf); try this: register int i = 1; register int c; /* Number each line. */ while ((c = getchar()) != EOF) { /* The number. */ printf("%d:\t%c", i++, c); /* The line. */ while ((c = getchar()) != EOF) { putchar(c); if (c == NL) break; } /* If you want to keep from extra passes: */ if (feof(stdin)) break; } return(0); /* Always return a value to the environment. */ -- Joe Yao hadron!jsdy@seismo.{CSS.GOV,ARPA,UUCP}
gwyn@brl-smoke.ARPA (Doug Gwyn ) (03/24/86)
In article <276@birtch.UUCP> ken@birtch.UUCP (Ken B) writes: > char c; > > c=getchar(); > if (c!=EOF) getchar() returns an (int), not a (char). EOF is an (int). You're throwing away some of the bits returned by getchar(), which happens not to matter in this case except when an EOF is returned. >This exact program works correctly on our Pyramid 90x, >so I know its not just my program. Oh, yes it is. The Pyramid presumably treats (char) as (signed char), while the 3B2 treats (char) as (unsigned char). Therefore the pyramid will propagate the sign of the 8-bit subset of the getchar() result that you stashed into c, whereas the 3B2 will not propagate the sign. You have a machine-dependent bug. Didn't "lint" catch this?
ken@birtch.UUCP (Ken B) (03/24/86)
Thank you to all of you that supplied me with the help (to my problem on the 3b2 not EOF-ing) 99% said the problem was the variable 'c' was defined as a 'char' and it should have been an 'int'. I changed it so, and it worked. Also, thanks to some of you for pointing out that the final 'putchar (EOF)' is not needed, and in fact, is not at all what I should have done. (it introduces one more character to the file that ought not to be there) Again, many thanks, Ken Brown -- uucp: ...{!glacier!oliveb,!ihnp4!trwrb} !felix!birtch!ken These ramblings are my own, and are surely not those of my employer.
throopw@dg_rtp.UUCP (Wayne Throop) (03/30/86)
> getchar() returns an (int), not a (char). EOF is an (int). > You're throwing away some of the bits returned by getchar(), > [...etc,etc...] > Didn't "lint" catch this? What, you didn't try it? Why not? :-) Anyhow, feeding this #include <stdio.h> void main(){ char c; while( (c = getchar()) != EOF ) ; } to SysV lint gives warning: nonportable character comparison Myself, I'd druther see lint complain whenever the types fed to an assignment don't match exactly, rather than allow "implicit casts", but the fact that quoted characters are of type int kind of spoils this idea for C, I suspect. -- Wayne Throop at Data General, RTP, NC <the-known-world>!mcnc!rti-sel!dg_rtp!throopw
dab@myrias.UUCP (Danny Boulet) (03/30/86)
something to say first... The problem is that getchar returns an int (not a char). I've never used either of the machines that you mention but my guess is that the Pyramid does sign extension on char to int conversions and the 3B2 doesn't. Since EOF is an integer (-1), the value 0xff gets assigned to your variable 'c'. When you compare this character with EOF (-1) on a machine that does sign extension, you get -1 vs -1. On a machine that doesn't do sign extension, you get 255 vs -1. The solution is simple - declare 'c' as an int instead of as a char.