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.cswollman@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.