www.delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp/2001/04/06/23:45:44

From: Jack Klein <jackklein AT spamcop DOT net>
Newsgroups: comp.os.msdos.djgpp
Subject: Re: Read with C++ <fstream.h>
Message-ID: <a62tctoks928qjn3vst926idt2vdao4arc@4ax.com>
References: <3ace2c09 DOT 4fbe DOT 0 AT surfeu DOT fi>
X-Newsreader: Forte Agent 1.8/32.548
MIME-Version: 1.0
Lines: 115
Date: Sat, 07 Apr 2001 03:39:30 GMT
NNTP-Posting-Host: 12.75.152.30
X-Complaints-To: abuse AT worldnet DOT att DOT net
X-Trace: bgtnsc04-news.ops.worldnet.att.net 986614770 12.75.152.30 (Sat, 07 Apr 2001 03:39:30 GMT)
NNTP-Posting-Date: Sat, 07 Apr 2001 03:39:30 GMT
Organization: AT&T Worldnet
To: djgpp AT delorie DOT com
DJ-Gateway: from newsgroup comp.os.msdos.djgpp
Reply-To: djgpp AT delorie DOT com

On Fri, 6 Apr 2001 23:50:17 +0300, "Mr. Veli Suorsa"
<VJSuorsa AT Surfeu DOT Fi> wrote in comp.os.msdos.djgpp:

> Hi!
> 
> Can You help me to convert this ascii- file reader (tested C program) to Gnu
> C++ using <fstream.h> library?
> 
> And how do you put these read lines to an array ( lines[MAXLINELEN][ROW] )?
> 
> 
> ---
> /* Program read lines from file.
>    (strread.c), Veli Suorsa, 06.04.2001 */
> 
> #include <stdio.h>
> 
> #define MAXLINELEN 110
> 
> int main( int argc, char *argv[] )
> {
>    char filename[30], strline[MAXLINELEN];
>    int line = 0;
>    FILE *fileptr;
> 
>    // Test if given parameter
>    if ( argc != 2 )
>    {
>       printf( "\nGive data file name : " );
>       gets( filename );

Have you tested this by typing in a filename that is 40 bytes, or 50
bytes, or 100 bytes?  gets() is still in the standard library because
a long, long time ago it was used by some very sloppy programmers.  It
is the most dangerous function in the entire C or C++ library because
there is literally no way to use it safely.  If the data entered is
larger than the buffer there is no way to prevent undefined behavior.

>    }
>    else
>    {
>       // Copy parameter to filename
>       strcpy( filename, argv[1] );

Again, DOS with short file names allows path names to have 64
characters, 63 visible characters plus one for the '\0' at the end.

>    }
> 
>    // Test if can read file
>    if ( ( fileptr = fopen( filename, "r" ) ) == NULL )
>    {
>       printf( "\nError: File: %s can't read.\n", filename );
>       exit(0);

You need to include <stdlib.h> for the prototype of exit.

>    }
> 
>    // List file
>    printf( "\nFile %s list :\n", filename );
> 
>    // Read and list, while not end of file
>    while ( !feof( fileptr ))
>    {
>       fgets( strline, MAXLINELEN, fileptr);

This is the wrong way to read a file from beginning to end.  The
feof() function does not work the way you think it does.  It does not
return true just because you already read the last byte of the file.
It returns an error flag that is set only after you try to read past
the end of the file.

The proper way to do this is to combine the read and test at the same
time.  Replace all three lines above with this:

      while (NULL != fgets(strline, sizeof strline, fileptr)
      {

>       printf( "%s", strline);
>       // Line counter
>       line++;
>    }
>    // Close file
>    fclose( fileptr );
> 
>    printf( "\n*** Read: %d rows from file: %s.\n", line, filename );
> 
>    return 0;
> }
> ---

For a safe replacement for gets() see
http://home.att.net/~jackklein/ctips01.html#safe_gets

For more information on why you are using feof() incorrectly and
gets() see these two topics from the FAQ for comp.lang.c:

12.2 Why won't the code `` while(!feof(infp)) { fgets(buf, MAXLINE,
infp); fputs(buf, outfp); } '' work?

12.23 Why does everyone say not to use gets()?

There is a link to the FAQ in my signature.

Perhaps you should correct the C version before attempting to
translate to C++.

-- 
Jack Klein
Home: http://JK-Technology.Com
FAQs for
comp.lang.c http://www.eskimo.com/~scs/C-faq/top.html
comp.lang.c++ http://www.parashift.com/c++-faq-lite/
alt.comp.lang.learn.c-c++ ftp://snurse-l.org/pub/acllc-c++/faq

- Raw text -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019