ian@ipse2pt5.cs.man.ac.uk (Ian Cottam) (02/08/91)
I typed this in because I waited a while and no one else did. (Of course, five minutes ago I just got one over the net :-) !) Anyway, here it is; in case people would like something to criticise. Thanks to a local user for comments (Stephen Bevan). K&R I people will have to hack-out the ANSI stuff. ___________________________________________________cut here_____________ /* Ian Cottam FEB 91 -- donated to public domain. */ #include <stdio.h> #include <string.h> #include <stddef.h> /* * fgetline(FILE *f) - returns a pointer to the start of a line read * from f, or the null pointer on any error or eof. * Like fgets(), you may well want to get rid of the * \n at the end (if any), and check feof(f)! This is * not a wonderful interface, but it mimics fgets(). * Caller should free memory if desired. */ #ifndef FGETLINE_BUFFSIZE # define FGETLINE_BUFFSIZE 20 #endif #if FGETLINE_BUFFSIZE < 2 #error FGETLINE_BUFFSIZE must be > 1 #endif char * fgetline(FILE *f) { extern void *malloc(size_t); extern void free(void *); char *buffer= (char *)malloc(FGETLINE_BUFFSIZE); char *result; if (buffer == NULL) return NULL; /*out of memory*/ result= fgets(buffer, FGETLINE_BUFFSIZE, f); if (result == NULL) return NULL; /* either error or at eof */ if (buffer[strlen(buffer)-1] != '\n' && !feof(f)) { /* longer line than buffer can hold */ char *restofline= fgetline(f); char *longline; if (restofline == NULL) return NULL; /*eof or error*/ longline= (char *)malloc(strlen(buffer)+strlen(restofline)+1); if (longline == NULL) return NULL; /*out of memory*/ (void) strcat(strcpy(longline, buffer), restofline ); free(restofline); free(buffer); return longline; } else return buffer; } -- Ian Cottam, Room IT209, Department of Computer Science, University of Manchester, Oxford Road, Manchester, M13 9PL, U.K. Tel: (+44) 61-275 6157 FAX: (+44) 61-275-6280 Internet: ian%cs.man.ac.uk; JANET: ian@uk.ac.man.cs
wollman@emily.uvm.edu (Garrett Wollman) (02/11/91)
Well, here is my version of the get-an-indefinite-length-string routine. I call it frgets, and it acts very much like gets(). I uses malloc to get memory. [Please note that I don't claim that it's at all efficient, but it makes the most sense to me. PErhaps a good compiler can make something of it.] #include <stdio.h> static char *frgets_h(FILE *fp,int accum) { int c = fgetc(fp); char *retval; if((c == EOF)||(c == '\n')) { retval = malloc(accum+1); if(retval) retval[accum] = '\0'; return(retval); } /* we didn't get an EOF or newline */ retval = frgets_h(fp,accum+1); if(retval) retval[accum] = (char)c; /* this may need fudging for signed chars < 0 */ return(retval); } char *frgets(FILE *fp) { return(frgets_h(fp,0)); } ---------- Note that, if there is not enough memory available deep in the recursion, then you lose all those characters that were read it. Too bad. I think that if you can't malloc enough for a simple string, that's probably the worst of your problems. No doubt all the other readers of comp.lang.c will come down from on high and condemn this. That's too bad too. -GAWollman Garrett A. Wollman - wollman@emily.uvm.edu Disclaimer: I'm not even sure this represents *my* opinion, never mind UVM's, EMBA's, EMBA-CF's, or indeed anyone else's.