Path: utzoo!utgpu!watmath!clyde!att!osu-cis!tut.cis.ohio-state.edu!bloom-beacon!mit-eddie!uw-beaver!uw-june!uw-entropy!dataio!bright From: bright@Data-IO.COM (Walter Bright) Newsgroups: comp.lang.c Subject: Re: Retiring gets Keywords: gets Message-ID: <1772@dataio.Data-IO.COM> Date: 5 Dec 88 18:26:32 GMT References: <649@umecs.cs.umu.se> Reply-To: bright@dataio.Data-IO.COM (Walter Bright) Organization: Data I/O Corporation; Redmond, WA Lines: 70 In article <649@umecs.cs.umu.se> eao@zeus.umu.se () writes: >When I retire gets() I would like a function like this fgetline() to replace >it. Are there any drawbacks I have missed? or is recursion to simple to use >in problems like this? (To parse a input in search of newline.) >/* > * char *fgetline(file) > * FILE *file; > * returns a null terminated line from stdin allocated with *some_malloc > */ > [ code deleted for brevity ] My objections to the code presented are: 1. It depends on static variables. This makes it non-reentrant, and therefore a bug waiting to happen on multi-threaded systems like OS2. 2. If a 0 byte is read, the behavior is undefined. So I present this: size_t fgetline(FILE *file, char **pbuffer, size_t *pbufsize); Semantics: Reads a line from the file. The end of the line is defined by reading a \n, or encountering the EOF. If a \n was read, it's included in the read line. 0s may also be read, and are included in the read line, thus the count of bytes read that's returned may be larger than that obtained by strlen(*pbuffer). Input: file input stream pointer pbuffer pointer to the buffer pointer. If the buffer pointer is NULL, one is malloc'd. The buffer pointer must be NULL or point to data allocated by malloc, realloc or calloc. pbufsize pointer to variable containing the allocated length of the buffer Output: *pbuffer If the buffer needs to be realloc'd, this is set to the new buffer. *pbufsize Set to the size of the buffer, which may be larger than the actual amount of data in the buffer. Errors: If EOF or an error occurs while a partially read line is being read, it is treated as the end of the line. If no bytes are read yet, 0 is returned. If malloc or realloc run out of memory, fgetline will return what it's already got, and errno will be set. Returns: number of bytes read into *pbuffer, excluding terminating 0 Example (in ANSI C): typefile(FILE *f) /* copy file to stdout */ { char *buffer = NULL; size_t buflen = 0; size_t linelen; while (1) { linelen = fgetline(f,&buffer,&buflen); if (linelen == 0) /* error or EOF */ break; if (fwrite(buffer,1,linelen,stdout) != linelen) break; /* error */ } free(buffer); } Put a quarter in the juke, Boogie 'till yah puke.