views:

10196

answers:

9

I wanted to use fstream to read a txt file.

I am using inFile >> characterToConvert, but the problem is that this omits any spaces and newline.

I am writing an encryption program so i need to include the spaces and newlines and was wondering what would be the proper way to go about accomplishing this.

Thanks in advance,

Tomek

A: 

The following c++ code will read an entire file...


#include <iostream>
#include <fstream>
#include <string>
using namespace std;

int main () 
{
  string line;
  ifstream myfile ("foo.txt");

  if (myfile.is_open()){

    while (!myfile.eof()){
      getline (myfile,line);
      cout << line << endl;
    }
    myfile.close();
  }
  return 0;
}

post your code and I can give you more specific help to your problem...

mmattax
+10  A: 

For encryption, you're better off opening your file in binary mode. Use something like this to put the bytes of a file into a vector:

std::ifstream ifs("foobar.txt", std::ios::binary);

ifs.seekg(0, std::ios::end);
std::ifstream::pos_type filesize = ifs.tellg();
ifs.seekg(0, std::ios::beg);

std::vector<char> bytes(filesize);

ifs.read(&bytes[0], filesize);

Edit: fixed a subtle bug as per the comments.

luke
Sorry, this has a subtle bug. Overload of 'seekg' that takes only an offset is called and you end up reading only two bytes (the value of 'std::ios:end). You should be calling seekg(0, std::ios::end) and seekg(0, std::ios::beg).
Alex B
Nice catch. Should be correct now.
luke
A: 

I haven't tested this, but I believe you need to clear the "skip whitespace" flag:

inFile.unsetf(ios_base::skipws);

I use the following reference for C++ streams: IOstream Library

Adam
A: 

For encryption, you should probably use read(). Encryption algorithms usually deal with fixed-size blocks. Oh, and to open in binary mode (no translation frmo \n\r to \n), pass ios_base::binary as the second parameter to constructor or open() call.

Arkadiy
A: 

You can call int fstream::get(), which will read a single character from the stream. You can also use istream& fstream::read(char*, streamsize), which does the same operation as get(), just over multiple characters. The given links include examples of using each method.

I also recommend reading and writing in binary mode. This allows ASCII control characters to be properly read from and written to files. Otherwise, an encrypt/decrypt operation pair might result in non-identical files. To do this, you open the filestream with the ios::binary flag. With a binary file, you want to use the read() method.

jdmichal
+9  A: 

Probably the best way is to read the entire file's contents into a string, which can be done very easily using ifstream's rdbuf() method:

std::ifstream in("myfile");

std::stringstream buffer;
buffer << in.rdbuf();

std::string contents(buffer.str());

You can then use regular string manipulation now that you've got everything from the file.

While Tomek was asking about reading a text file, the same approach will work for reading binary data, though the std::ios::binary flag needs to be provided when creating the input file stream.

Jason Etheridge
+2  A: 

A lot of the benefit of the istream layer is providing basic formatting and parsing for simple types ro and from a stream. For the purposes that you describe, none of this is really important and you are just interested in the file as a stream of bytes.

For these purpose you may be better of just using the basic_streambuf interface provided by a filebuf. The 'skip whitespace' behaviour is part of the istream interface functionality that you just don't need.

filebuf underlies an ifstream, but it is perfectly valid to use it directly.

std::filebuf myfile;
myfile.open( "myfile.dat", std::ios_base::in | std::ios_base::binary );

// gets next char, then moves 'get' pointer to next char in the file
int ch = myfile.sbumpc();

// get (up to) the next n chars from the stream
std::streamsize getcount = myfile.sgetn( char_array, n );

Also have a look at the functions snextc (moves the 'get' pointer forward and then returns the current char), sgetc (gets the current char but doesn't move the 'get' pointer) and sungetc (backs up the 'get' pointer by one position if possible).

When you don't need any of the insertion and extraction operators provided by an istream class and just need a basic byte interface, often the streambuf interface (filebuf, stringbuf) is more appropriate than an istream interface (ifstream, istringstream).

Charles Bailey
A: 

As Charles Bailey correctly pointed out, you don't need fstream's services just to read bytes. So forget this iostream silliness, use fopen/fread and be done with it. C stdio is part of C++, you know ;)

Constantin
But by using streams the stream need not be just a file.It could be a string a socket or anything else you like. streambuf_iterator<>
Martin York
I agree, but OP specifically stated the goal was "to read a txt file".
Constantin
A: 

Simple

#include <fstream>
#include <iomanip>


ifstream ifs ("file");
ifs >> noskipws

that's all.

Flame