Using C++ ifstream extraction operator>> to read formatted data from a file

goldenmean picture goldenmean · Sep 16, 2011 · Viewed 61.1k times · Source

As my learning, I am trying to use c++ ifstream and its operator>> to read data from a text file using code below. The text file outdummy.txt has following contents:

just dummy
Hello ofstream
555

My questions is how to read char data present in the file into a char array or string. How to do this using the ifstream::operator>> in code below.

#include <iostream>
#include <fstream>

int main()
{
    int a;
    string s;
    char buf[100];
    ifstream in("outdummy.txt",ios_base::in);


    in.operator>>(a); //How to read integer? How to read the string data.??

    cout << a;

    in.close();
    getchar();
    return 0;
}

Answer

Kerrek SB picture Kerrek SB · Sep 16, 2011

If you want to use formatted input, you have to know in advance what data to expect and read it into variables of the according data type. For example, if you know that the number is always the fifth token, as in your example, you could do this:

std::string s1, s2, s3, s4;
int n;

std::ifstream in("outdummy.txt");

if (in >> s1 >> s2 >> s3 >> s4 >> n)
{
  std::cout << "We read the number " << n << std::endl;
}

On the other hand, if you know that the number is always on the third line, by itself:

std::string line;

std::getline(in, line);  // have line 1
std::getline(in, line);  // have line 2
std::getline(in, line);  // have line 3

std::istringstream iss(line);

if (iss >> n)
{
  std::cout << "We read the number " << n << std::endl;
}

As you can see, to read a token as a string, you just stream it into a std::string. It's important to remember that the formatted input operator works token by token, and tokens are separated by whitespace (spaces, tabs, newlines). The usual fundamental choice to make is whether you process a file entirely in tokens (first version), or line by line (second version). For line-by-line processing, you use getline first to read one line into a string, and then use a string stream to tokenize the string.


A word about validation: You cannot know whether a formatted extraction will actually succeed, because that depends on the input data. Therefore, you should always check whether an input operation succeeded, and abort parsing if it doesn't, because in case of a failure your variables won't contain the correct data, but you have no way of knowing that later. So always say it like this:

if (in >> v) { /* ... */ }            // v is some suitable variable
else { /* could not read into v */ }

if (std::getline(in, line)) { /* process line */ }
else { /* error, no line! */ }

The latter construction is usually used in a while loop, to read an entire file line by line:

while (std::getline(in, line)) { /* process line */ }