Re: Replacing fgets




CBFalconer <cbfalconer@xxxxxxxxx> wrote in message
news:450DE59F.FD347C@xxxxxxxxxxxx
Bill Reid wrote:
CBFalconer <cbfalconer@xxxxxxxxx> wrote in message

... snip ...

I suggest you try ggets, which is written in pure standard C, and
is available at:

<http://cbfalconer.home.att.net/download/>

OK, for the sake of discussion, replacing fgets() with some type
of equivalent function where you START with a unopened file really
doesn't get you much, EXCEPT when you want to do interactive editing
of the file contents (fgets() is fine for general parsing and
searching), and in that case you probably want something more than
an equivalent of the largely brain-dead fgets().

You obviously didn't download and try ggets. It is a replacement
for gets and fgets. It is not a clone. It has different
parameters and semantics.

You're right, I didn't look at it, I was just perambulating on the
general pointlessness of opening a file, reading it to a buffer, then
using a simple work-alike for fgets() (and ftell(), fseek(), rewind()).

To further the pointlessness, I noticed that the comments and the
code I posted were a little "off", and also recognize that some people
might find it offensive to read perhaps hundreds of lines just to
reset the buffer position. So I fixed the nits and added an argument
to allow you to only set the position without reading the buffer, with
a couple new macros for mnemonics:

#define POSITION 0 /* don't get line, just position for next
*/
#define GETLINE 1 /* get the line at current position */

....

/* like fgets() except works on a text buffer rather than a file stream
each call gets next line in buffer, returns start of line that is read
so is also kind of like ftell(), if you used ftell() before each fgets()
you can also "rewind()" function by passing FIRSTLINE as "start"
and you can run an entire loop by passing NEXTLINE as "start"
last call for buffer gets nothing, returns ENDOFTEXT, function is reset
if you only want to set buffer position, pass POSITION as "operation"
if you want to actually get the line, pass GETLINE */
unsigned long get_text_line
(char *text_buf,char *line_buf,unsigned long start,unsigned operation) {
static unsigned long text_idx;
unsigned long line_start=text_idx;
unsigned line_idx=0;

if(start==FIRSTLINE) line_start=text_idx=FIRSTLINE;

else if(start!=NEXTLINE) line_start=text_idx=start;

if(operation==POSITION) return line_start;

while(line_idx<LINEMAX) {

line_buf[line_idx]=text_buf[text_idx];
if(text_buf[text_idx]=='\0') break;

if(text_buf[text_idx]=='\n') {
line_buf[line_idx]='\0';
text_idx++,line_idx++;
break;
}
text_idx++,line_idx++;
}

if(line_idx==0) {
text_idx=0;
return ENDOFTEXT;
}
else return line_start;
}

And here are some more examples of how you can use it:

unsigned check_read_file_function(void) {
FILE *test_file;
char choice[16];
char filename[32];
char *file_buffer=NULL;
char test_line_buf[LINEMAX];
unsigned long line_start=0,search_line,stop_line;

printf("\nEnter file name: ");
gets(filename);

if((test_file=fopen(filename,"rt"))==NULL) {
fprintf(stderr,"Can't open test file %s\n",filename);
return FALSE;
}

if(!(read_file_to_buffer(test_file,&file_buffer))) {
printf("\nCouldn't read test file to buffer");
fclose(test_file);
free(file_buffer);
file_buffer=NULL;
return FALSE;
}

fclose(test_file);

/* now read the whole thing */
while((get_text_line(file_buffer,test_line_buf,NEXTLINE,GETLINE))
!=ENDOFTEXT)
puts(test_line_buf);

printf("That was printing out file from buffer - press RETURN\n\n");
gets(choice);

/* now read the whole thing...AGAIN! */
while((get_text_line(file_buffer,test_line_buf,NEXTLINE,GETLINE))
!=ENDOFTEXT)
puts(test_line_buf);

printf("That was printing out file from buffer AGAIN - press
RETURN\n\n");
gets(choice);

/* now find a search string, and save the position */
while(search_line!=ENDOFTEXT) {
search_line=
get_text_line(file_buffer,test_line_buf,NEXTLINE,GETLINE);
if((strncmp(test_line_buf,"mid-file line search",20))==0) break;
}

/* now position search string line again, but don't get it */
get_text_line(file_buffer,test_line_buf,search_line,POSITION);

/* now read and print the rest of the file */
while((get_text_line(file_buffer,test_line_buf,NEXTLINE,GETLINE))
!=ENDOFTEXT)
puts(test_line_buf);

printf("That was printing file down FROM search string - press
RETURN\n\n");
gets(choice);

/* find the search string again, and save the position */
while(search_line!=ENDOFTEXT) {
search_line=
get_text_line(file_buffer,test_line_buf,NEXTLINE,GETLINE);
if((strncmp(test_line_buf,"mid-file line search",20))==0) {
stop_line=search_line;
break;
}
}

/* "rewind()" back to the first line, but don't get it */
line_start=
get_text_line(file_buffer,test_line_buf,FIRSTLINE,POSITION);

/* then print out all the lines up to the search string line */
line_start=FIRSTLINE;
while(line_start<stop_line) {
line_start=
get_text_line(file_buffer,test_line_buf,NEXTLINE,GETLINE);
puts(test_line_buf);
}

printf("That was printing file down TO search string - press
RETURN\n\n");
gets(choice);

free(file_buffer);
file_buffer=NULL;

return TRUE;
}

As I said, this is really only useful for some simple parsing of buffers
that may have come from someplace other than a file, such as perhaps
downloaded from the Internet...

---
William Ernest Reid



.



Relevant Pages

  • Re: Replacing fgets
    ... Bill Reid wrote: ... OK, for the sake of discussion, replacing fgets() with some type ... reset the buffer position. ... if you only want to set buffer position, ...
    (comp.lang.c)
  • system() and _flushall()
    ... You must explicitly flush (using fflush or _flushall) or close any stream ... However, on the next read from the input file using fgets, I get ... forgotten that there's still data in the buffer (the buffer is not destroyed ...
    (microsoft.public.vc.language)
  • Re: *scanf in Harbison and Steele
    ... The difference between fgets and gets is at least that fgets takes ... the output buffer. ... Though I've been told that stdin come with the food in C, must you declare: ...
    (comp.lang.c)
  • Re: user input, getchar, and buffer - For C beginners and those with teaching skills...
    ... buffer: video streaming, printer jobs. ... > Fgets unlike scanf has a limit in the number of caracters ... to read any newline left (here it would be located in array> "chaine" ... than 20 characters and keeps it in the buffer? ...
    (comp.lang.c)
  • Re: Best way to input from stdin?
    ... I intend to use the code in that snippet to simply fill a buffer from a file that is then used by a parser to build a document tree. ... If a line is too long for the buffer, fgets() will read as ... filling all but the last buffer position with ...
    (comp.lang.c)