dave@cs.arizona.edu (Dave P. Schaumann) (02/25/91)
In article <38192@netnews.upenn.edu> widyono@eniac.seas.upenn.edu (Aasmodeus) writes: >int getline(FILE *fp, char *line); /* decl. should it be line[]? */ > >main(int argc, char *argv[]) >{ > char line[BUFSIZ]; /* line of input */ > while (getline(fp, line) > 0) { > printf("%s\n", *line); This is it ---------^ line is an array. *line is the first character of that array. When printf sees "%s", it takes whatever the second parameter is, and tries to indirect through it. You can get the same effect by saying char c = 'x' ; *c = 'y' ; A computer that has any kind of memory protection will almost certainly have a segmentation fault at this point. > if (fgets(line, BUFSIZ, fp) == NULL) Here is another, more subtle bug. fgets will write up to BUFSIZ characters (in this call) to line. This is not including the final '\0' character. The best thing to do is declare char line[BUFSIZ + 1], and all will be well. -- Dave Schaumann | Is this question undecidable? dave@cs.arizona.edu |
dave@cs.arizona.edu (Dave P. Schaumann) (02/25/91)
Sorry if this appears twice. The first time I tried to follow up, it appeared that nothing actually got posted... In article <38192@netnews.upenn.edu> widyono@eniac.seas.upenn.edu (Aasmodeus) writes: >int getline(FILE *fp, char *line); /* decl. should it be line[]? */ > >main(int argc, char *argv[]) >{ > char line[BUFSIZ]; /* line of input */ > while (getline(fp, line) > 0) { > printf("%s\n", *line); This is it ---------^ line is an array. *line is the first character of that array. When printf sees "%s", it takes whatever the second parameter is, and tries to indirect through it. You can get the same effect by saying char c = 'x' ; *c = 'y' ; A computer that has any kind of memory protection will almost certainly have a segmentation fault at this point. > if (fgets(line, BUFSIZ, fp) == NULL) Here is another, more subtle bug. fgets will write up to BUFSIZ characters (in this call) to line. This is not including the final '\0' character. The best thing to do is declare char line[BUFSIZ + 1], and all will be well. -- Dave Schaumann | Is this question undecidable? dave@cs.arizona.edu |
dbc@cimage.com (David Caswell) (02/26/91)
In article <19099:Feb2505:49:2891@kramden.acf.nyu.edu> brnstnd@kramden.acf.nyu.edu (Dan Bernstein) writes: .> > char line[BUFSIZ]; /* line of input */ . [ ... ] .> > if (fgets(line, BUFSIZ, fp) == NULL) .> Here is another, more subtle bug. fgets will write up to BUFSIZ characters .> (in this call) to line. This is not including the final '\0' character. .> The best thing to do is declare char line[BUFSIZ + 1], and all will be well. . .Uh, no. The fgets() interface was designed so that you could do things .like fgets(line,sizeof(line),fp). Here it reads at most BUFSIZ - 1 .characters before the terminating null. That is why it is so funny to see people do while(fgets(str,1,fp)){ ... } for character-at-a-time input.
allbery@NCoast.ORG (Brandon S. Allbery KB8JRR) (03/03/91)
As quoted from <944@caslon.cs.arizona.edu> by dave@cs.arizona.edu (Dave P. Schaumann): +--------------- | > if (fgets(line, BUFSIZ, fp) == NULL) | | Here is another, more subtle bug. fgets will write up to BUFSIZ characters | (in this call) to line. This is not including the final '\0' character. | The best thing to do is declare char line[BUFSIZ + 1], and all will be well. +--------------- fgets writes BUFSIZ-1 characters in all Unix and Unix-like systems I have encountered, specifically to leave room for the trailing \0. RTFM. ++Brandon -- Me: Brandon S. Allbery VHF/UHF: KB8JRR on 220, 2m, 440 Internet: allbery@NCoast.ORG Packet: KB8JRR @ WA8BXN America OnLine: KB8JRR AMPR: KB8JRR.AmPR.ORG [44.70.4.88] uunet!usenet.ins.cwru.edu!ncoast!allbery Delphi: ALLBERY