home *** CD-ROM | disk | FTP | other *** search
/ NetNews Usenet Archive 1992 #16 / NN_1992_16.iso / spool / comp / lang / c / 11647 < prev    next >
Encoding:
Internet Message Format  |  1992-07-27  |  2.8 KB

  1. Path: sparky!uunet!haven.umd.edu!darwin.sura.net!wupost!gumby!destroyer!ncar!noao!amethyst!organpipe.uug.arizona.edu!news
  2. From: dave@cs.arizona.edu (Dave Schaumann)
  3. Newsgroups: comp.lang.c
  4. Subject: Re: compiler broken?
  5. Message-ID: <1992Jul27.183758.29832@organpipe.uug.arizona.edu>
  6. Date: 27 Jul 92 18:37:58 GMT
  7. References: <1992Jul25.054848.11223@wyvern.twuug.com>
  8. Sender: news@organpipe.uug.arizona.edu
  9. Reply-To: dave@cs.arizona.edu (Dave Schaumann)
  10. Organization: University of Arizona
  11. Lines: 62
  12. In-Reply-To: alpha@wyvern.twuug.com (Joe Wright)
  13.  
  14. In article <1992Jul25.054848.11223@wyvern.twuug.com>, alpha@wyvern (Joe Wright) writes:
  15. >rdlin() {
  16. >    int i;
  17. >    for (i = 0; i < length && ((record[i] = getc(infile)) != EOF); ++i)
  18. >        ;
  19. >    return i;
  20. >}
  21. >
  22. >It worked fine on my C/80 system but failed on another i486 Unix
  23. >system.  It turned out that if the character read was 0xff it was
  24. >promoted to -1 (EOF) and caused an 'early' exit.
  25.  
  26. You left out the declaration of record[], but from your problem, I
  27. bet you have it declared as "char record[N]", or something similar.
  28. Moreover, I'll bet chars are unsigned on your C/80, and signed on
  29. the Unix box.
  30.  
  31. Your problem (assuming my guesses are correct) is in the expression
  32.  
  33.   (record[i] = getc(infile)) != EOF
  34.  
  35. If record[i] is of type char, then the value of the assignment statement
  36. will be of type char, too.  That means if you have signed chars, 0xFF gets
  37. promoted to (int) -1, and matches EOF.  If you have unsigned chars, this
  38. promotion does not happen.
  39.  
  40. However, if you have unsigned chars, when EOF is encountered, the value
  41. is first truncated to 0xff by the assignment statement, so it never
  42. matches the EOF statement.  That means all remaining records are filled
  43. with (char)EOF, which may or may not matter to the rest of your program.
  44.  
  45. >I fixed it:
  46. >
  47. >rdlin() {
  48. >    int c, i;
  49. >    for (i = 0; i < length; ++i) {
  50. >        if ((c = getc(infile)) == EOF)
  51. >            break;
  52. >        record[i] = c;
  53. >    }
  54. >    return i;
  55. >}
  56.  
  57. Notice how here, the assignment statement results in an int, so no
  58. information is lost when EOF is encountered, and 0xff is not erroneously
  59. promoted when it is encountered.
  60.  
  61. Also, you probably want to put a '\0' after the end of the data in your
  62. array, since many of C's string-handling functions depend on it being there.
  63. You should probably also re-think the wisdom of making "record", "length",
  64. and "infile" global to a routine of such general utility as reading in a
  65. string.  In fact, you may wish to investigate fgets(), which is a library
  66. routine that performs virtually the same task as the code presented above.
  67.  
  68. >Question:  Is the Unix compiler broken?  
  69.  
  70. No, I don't think so.
  71.  
  72. -- 
  73. You're traveling through another dimension -- a dimension not only of sight and
  74. sound but of mind. A journey into a wonderous land whose boundaries are that of
  75. imagination.  That's a signpost up ahead: your next stop: the Twilight Zone!
  76.