From: Jack Klein Newsgroups: comp.os.msdos.djgpp Subject: Re: Read with C++ Message-ID: References: <3acf99f6 DOT 7c0b DOT 0 AT surfeu DOT fi> X-Newsreader: Forte Agent 1.8/32.548 MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit Lines: 175 Date: Sun, 08 Apr 2001 03:01:48 GMT NNTP-Posting-Host: 12.75.172.27 X-Complaints-To: abuse AT worldnet DOT att DOT net X-Trace: bgtnsc06-news.ops.worldnet.att.net 986698908 12.75.172.27 (Sun, 08 Apr 2001 03:01:48 GMT) NNTP-Posting-Date: Sun, 08 Apr 2001 03:01:48 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 Sun, 8 Apr 2001 01:51:34 +0300, "Mr. Veli Suorsa" wrote in comp.os.msdos.djgpp: > Hi! > > Thanks for your reply! > > >On Fri, 6 Apr 2001 23:50:17 +0300, "Mr. Veli Suorsa" > > wrote in comp.os.msdos.djgpp: > >> > >> Can You help me to convert this ascii- file reader > >> (tested C program) to Gnu C++ using 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 > >> > >> #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. > > Don't be so crude. > I Compile and test this program with filenames under 30 bytes. But I understand > that "safety", you emphasize. What was that english hacker who break into Mr > Gates files and order him viagra? > > >> } > >> 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. > > OK, I will use longer variable... > > >> } > >> > >> // 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 for the prototype of exit. > > Why? It works fine with ! It works "by accident" in most C compilers, although technically it is undefined behavior. If you call a function in C with no declaration or prototype in scope, the compiler assumes that it returns an int and takes a fixed number of arguments that match the values you call it with after any default promotions. But exit() has a return type of void, not int (actually it doesn't return), so you are have a function type mis-match. In any case, C++ requires that all functions have a complete prototype in scope, it is not optional like it was in C up until the 1999 standard update and still is in DJGPP. So C++ will require you to include to call exit, or write your own prototype for it, which is definitely not recommended for standard library functions. > > >> } > >> > >> // 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) > > { > > I will try this. "My way" works, too, indeed. > > >> 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 > > Thanks for this link. > > >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++. > > C version works fine (with a little finishing touches)! > > Can you help me with this C++ conversion? > > And how do you put these read lines to an array ( lines[MAXLINELEN][ROW] )? > > > >-- > >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 > > > > With Best Regards! > > Veli Suorsa > --- > "People must believe to the future to be able to live!" > ---------------------------------- J.V.Snellman, 1890. > > Oulu, FINLAND > Mailto:VJSuorsa AT Surfeu DOT Fi > http://members.surfeu.fi/veli.suorsa/ > http://www.surfeu.fi