Connecting Tech Pros Worldwide Forums | Help | Site Map

Stroustrup Section 7.10, Exercise 4

arnuld
Guest
 
Posts: n/a
#1: Nov 5 '08
This one works to seem fine. Can I make this program better ?

1) the use of get(ch) function was inspired from Stroustrup 21.5.1, page
number 638.
2) I see, when you create an object of std::ifstream while passing a
pointer to it, it automatically opens the file.

3) If I open a file using std::ostream, then I am confused whether it
will open the file for writing or appending ?.



/* Section 7.10: Exercise 4
*
* Write a program that reads arbitrary number of files (whose names are
* given as command-line arguments) and writes them to one after another
* on std::cout.
*
* My view: It feels like UNIX cat
*
* VERSION: 1.0
*
*/

#include <iostream>
#include <cstdlib>
#include <fstream>
#include <algorithm>
#include <iterator>


int print_file( char* );


int main(int argc, char* argv[] )
{
if( 1 == argc )
{
std::cerr << "No Input File\n";
exit( EXIT_FAILURE );
}


int file_count = (argc - 1);
int idx = 1;
while( file_count-- )
{
if( print_file( argv[idx] ) )
{
std::cerr << "error reading file: "
<< argv[idx]
<< std::endl;
}

++idx;
}


return 0;
}




int print_file( char* pc )
{
const int read_success = 0;
const int read_failure = 1;

std::ifstream ifile(pc);

if( (!ifile) )
{
ifile.close();
return read_failure;
}

char ch;
while( ifile.get(ch) )
{
std::cout << ch;
}

ifile.close();

return read_success;
}



--
www.lispmachine.wordpress.com
my email is @ the above blog.
Google Groups is UnBlocked now :)



arnuld
Guest
 
Posts: n/a
#2: Nov 6 '08

re: Stroustrup Section 7.10, Exercise 4


On Wed, 05 Nov 2008 14:48:54 +0100, Michael DOUBEZ wrote:

Quote:
You can also use std::copy with istream_ierator/ostream_iterator.
There is also the usage of rdbuf().

std::istream_iterator is what I wanted to use but I am getting lots of
garbage gets printed along with the file contents. See here is a file
which contains only one word: comp.lang.c++ and see how much garbage is
getting printed. 2nd, is it a god idea to put a for loop in main ?



/* Section 7.10: Exercise 4
*
* Write a program that reads arbitrary number of files (whose names are
* given as command-line arguments) and writes them to one after another
* on std::cout.
*
* My view: It feels like UNIX cat
*
* VERSION: 1.1
*
*/

#include <iostream>
#include <cstdlib>
#include <fstream>
#include <iterator>

int print_file( const char* );


int main(int argc, char* argv[] )
{
if( 1 == argc )
{
std::cerr << "No Input File\n";
exit( EXIT_FAILURE );
}


for( int i = 0; i != argc; ++i )
{
if( print_file( argv[i] ) )
{
std::cerr << "error reading file: "
<< argv[i]
<< std::endl;
}
}


return 0;
}



int print_file( const char* pc )
{
const int read_success = 0;
const int read_failure = 1;

std::ifstream ifile(pc);

if( (!ifile) ) return read_failure;

copy( std::istream_iterator<char>(ifile), std::istream_iterator<char>(),
std::ostream_iterator<char>(std::cout,"") );

// we don't need to close the file because the destructor for ifstream
// will automatically do it.
return read_success;
}


=================== OUTPUT =============================
[arnuld@dune cpp]$ g++4 -ansi -pedantic -Wall -Wextra 07-10_04.cpp
[arnuld@dune cpp]$ ./a.out
No Input File
[arnuld@dune cpp]$ ./a.out test.txt
44Qåtd/lib/ld-linux.so.2GNU


^[[?1;2c
)¼Ãð^[[?1;2cAÂEK<ÊHÍgÝORSÙ2¹XLð÷ Û=p

... LOTS OF GARBAGE SNIPPED.....
Áñÿ
R
ñÿ'À
ºñÿÙ!ñÿ(>ñÿC¹ñÿn}LÅû char_traitsIcEERSt13basic_InitD1Ev@@
^[[?1;2c^[[?1;2c^[[?1;2c^[[?1;2c^[[?1;2c^[[?1;2c[arnuld@dune cpp]$
1;2c1;2c1;2c1;2c1;2c1;2c1;2c1;2c1;2c1;2c1;2c<1;2c1 ;2c1;2c1;2c1;2c1;2c1;2c1;2c1;2c1;




--
www.lispmachine.wordpress.com
my email is @ the above blog.


arnuld
Guest
 
Posts: n/a
#3: Nov 6 '08

re: Stroustrup Section 7.10, Exercise 4


On Wed, 05 Nov 2008 14:48:54 +0100, Michael DOUBEZ wrote:
Quote:
You can also use std::copy with istream_ierator/ostream_iterator.
There is also the usage of rdbuf().
Here is what I am getting:

/* Section 7.10: Exercise 4
*
* Write a program that reads arbitrary number of files (whose names are
* given as command-line arguments) and writes them to one after another
* on std::cout.
*
* My view: It feels like UNIX cat
*
* VERSION: 1.2
*
*/

#include <iostream>
#include <cstdlib>
#include <fstream>
#include <iterator>

int print_file( const char* );


int main(int argc, char* argv[] )
{
if( 1 == argc )
{
std::cerr << "No Input File\n";
exit( EXIT_FAILURE );
}


for( int i = 1; i <= argc; ++i )
{
if( print_file( argv[i] ) )
{
std::cerr << "\n\n-------------------error reading file: "
<< argv[i]
<< " --------------------------------\n"
<< std::endl;
}
}

return 0;
}


int print_file( const char* pc )
{
const int read_success = 0;
const int read_failure = 1;

std::ifstream ifile(pc);

if( (!ifile) ) return read_failure;

copy( std::istream_iterator<std::string>(ifile), std::istream_iterator<std::string>(),
std::ostream_iterator<std::string>(std::cout," ") );

// we don't need to close the file because the destructor for ifstream
// will automatically do it.
return read_success;
}


========================= OUTPUT ===============================
[arnuld@dune cpp]$ g++4 -ansi -pedantic -Wall -Wextra 07-10_04.cpp
[arnuld@dune cpp]$ ./a.out test.txt


-------------------error reading file: comp.alng.c++ [arnuld@dune cpp]$


Why it is printing error reading file always ?


2nd, even if it is printing the error by some program mistake then why
it not full error, why only half error message ?



--
www.lispmachine.wordpress.com
my email is @ the above blog.


arnuld
Guest
 
Posts: n/a
#4: Nov 6 '08

re: Stroustrup Section 7.10, Exercise 4


On Thu, 06 Nov 2008 12:34:06 +0500, arnuld wrote:

Quote:
for( int i = 1; i <= argc; ++i )
This is the source of my all frustration. It should be < not <= :-\ . I
still have one question , using:

std::stream_terator<char>(ifile)

kills the formatting of the output. I mean the original file and output
are different in formatting but with:

while( ifile.get(ch) ) std::cout << ch;

the formatting remains the same. How can I keep formatting same with
istream_iterator ?



--
www.lispmachine.wordpress.com
my email is @ the above blog.


arnuld
Guest
 
Posts: n/a
#5: Nov 6 '08

re: Stroustrup Section 7.10, Exercise 4


On Thu, 06 Nov 2008 09:08:07 +0100, Michael DOUBEZ wrote:

Quote:
You need to read the white spaces; insert the following before copying:
ifile.unsetf(std::ios_base::skipws);
skipws means skip the white space (or don't read it) but you say with it
it will read the white space. So I am little confused and what unsetf is ?

Program is working fine though.


--
www.lispmachine.wordpress.com
my email is @ the above blog.


arnuld
Guest
 
Posts: n/a
#6: Nov 6 '08

re: Stroustrup Section 7.10, Exercise 4


On Thu, 06 Nov 2008 09:38:50 +0100, Michael DOUBEZ wrote:

Quote:
Yes but you unset it; unsetf remove the format flags specified in
parameters. In this case, it will remove the flag telling the stream to
skip whitespaces.
okay . I understand it now :)

Quote:
It is equivalent to:
char c;
ifile>>noskiws>>c;

Just a question. Why std::istream_iterator is created with an intention to
skip whitespace . Some specific reason ?




--
www.lispmachine.wordpress.com
my email is @ the above blog.


=?UTF-8?B?RXJpayBXaWtzdHLDtm0=?=
Guest
 
Posts: n/a
#7: Nov 8 '08

re: Stroustrup Section 7.10, Exercise 4


On 2008-11-05 12:48, arnuld wrote:
Quote:
This one works to seem fine. Can I make this program better ?
Quote:
int print_file( char* pc )
{
const int read_success = 0;
const int read_failure = 1;
I would declare those constants outside the function so that whoever
calls print_file can use them to test for success or not:

if( read_success == print_file( argv[idx] ) )

--
Erik Wikström
Closed Thread