1.10.  File Streams

[ fromfile: filestreams.xml id: filestreams ]

Streams are used for reading from or writing to files, network connections, and also strings. One useful feature of streams is that they make it easy to produce strings from mixed types of data. Example 1.11 creates some strings from characters and numerics and writes them to a file.

Example 1.11. src/stl/streams/streams.cpp

[ . . . . ]

#include <iostream>
#include <sstream>
#include <fstream>

int main() {
    using namespace std;
    ostringstream strbuf;

    int lucky = 7;
    float pi=3.14;
    double e=2.71;

    cout << "An in-memory stream" << endl;
    strbuf << "luckynumber: " << lucky << endl
           << "pi: " << pi << endl
           << "e: " << e << endl;

    string strval = strbuf.str(); 1
    cout << strval;

    ofstream outf;                2
    outf.open("mydata");          3
    outf << strval ;
    outf.close();

1

Convert the stringstream to a string.

2

An output file stream.

3

Creates (or overwrites) a disk file for output.


After the strings have been written, you have a couple of choices of how to read them. You can use simple input operators to read from the file and, because there is whitespace between records, the insertion operator might look like Example 1.12

Example 1.12. src/stl/streams/streams.cpp

[ . . . . ]

    cout << "Read data from the file - watch for errors." << endl;
    string newstr;
    ifstream inf;  1
    inf.open("mydata");
    if(inf) {  2
      int lucky2;
      inf >> newstr >> lucky2;
      if (lucky != lucky2)
        cerr << "ERROR! wrong " << newstr << lucky2  << endl;
      else
        cout << newstr << " OK" << endl;

      float pi2;
      inf >> newstr >> pi2;
      if (pi2 != pi)
        cerr << "ERROR! Wrong " << newstr << pi2 << endl;
      else
        cout << newstr << " OK" << endl;

      double e2;
      inf >> newstr >> e2;
      if (e2 != e)
        cerr << "ERROR: Wrong " << newstr << e2 <<  endl;
      else
        cout << newstr << " OK" << endl;
      inf.close();
    }

1

An input file stream

2

Make sure the file exists before attempting to read.


You can read files line-by-line and deal with each line as a single string, as shown in Example 1.13

Example 1.13. src/stl/streams/streams.cpp

[ . . . . ]

    cout << "Read from file line-by-line" << endl;
    inf.open("mydata");
    if(inf) {
      while (not inf.eof()) {
        getline(inf, newstr);
        cout << newstr << endl;
      }
      inf.close();
    }
    return 0;
}

Example 1.14 does the same things using Qt files, strings, and streams. This example also uses two other Qt types: QString, which provides a powerful and flexible string representation, and QFile, which provides an interface for handling files.

Example 1.14. src/qtstreams/files/qdemo.cpp

#include <QTextStream>
#include <QString>
#include <QFile>

QTextStream cout(stdout);
QTextStream cerr(stderr);

int main() {
  QString str, newstr;
  QTextStream strbuf(&str);             1

  int lucky = 7;
  float pi = 3.14;
  double e = 2.71;

  cout << "An in-memory stream" << endl;
  strbuf << "luckynumber: " << lucky << endl
	 << "pi: " << pi << endl
	 << "e: " << e << endl;

  cout << str;

  QFile data("mydata");
  data.open(QIODevice::WriteOnly);      2
  QTextStream out(&data);               3
  out << str ;
  data.close();

  cout << "Read data from the file - watch for errors." << endl;
  if(data.open(QIODevice::ReadOnly)) {  4
    QTextStream in(&data);              5
    int lucky2;
    in >> newstr >> lucky2;
    if (lucky != lucky2)
      cerr << "ERROR! wrong " << newstr << lucky2  << endl;
    else
      cout << newstr << " OK" << endl;

    float pi2;
    in >> newstr >> pi2;
    if (pi2 != pi)
      cerr << "ERROR! Wrong " << newstr << pi2 << endl;
    else
      cout << newstr << " OK" << endl;

    double e2;
    in >> newstr >> e2;
    if (e2 != e)
      cerr << "ERROR: Wrong " << newstr << e2 <<  endl;
    else
      cout << newstr << " OK" << endl;
    data.close();
  }

  cout << "Read from file line-by-line" << endl;
  if(data.open(QIODevice::ReadOnly)) {
    QTextStream in(&data);              6
    while (not in.atEnd()) {
      newstr = in.readLine();
      cout << newstr << endl;
    }
    data.close();
  }
  return 0;
}

1

strbuf is initialized with the address of str.

2

Creates (or overwrites) a disk file for output.

3

An output file stream.

4

Make sure the file exists before attempting to read.

5

An input file stream.

6

An input file stream.


Section 1.15.1 discusses the address-of operator, used to initialize strbuf.