Follow Techotopia on Twitter

On-line Guides
All Guides
eBook Store
iOS / Android
Linux for Beginners
Office Productivity
Linux Installation
Linux Security
Linux Utilities
Linux Virtualization
Linux Kernel
System/Network Admin
Programming
Scripting Languages
Development Tools
Web Development
GUI Toolkits/Desktop
Databases
Mail Systems
openSolaris
Eclipse Documentation
Techotopia.com
Virtuatopia.com
Answertopia.com

How To Guides
Virtualization
General System Admin
Linux Security
Linux Filesystems
Web Servers
Graphics & Desktop
PC Hardware
Windows
Problem Solutions
Privacy Policy

  




 

 

Thinking in C++
Prev Contents / Index Next

Reading and writing files

In C, the process of opening and manipulating files requires a lot of language background to prepare you for the complexity of the operations. However, the C++ iostream library provides a simple way to manipulate files, and so this functionality can be introduced much earlier than it would be in C.

To open files for reading and writing, you must include <fstream>. Although this will automatically include <iostream>, it’s generally prudent to explicitly include <iostream> if you’re planning to use cin, cout, etc.

To open a file for reading, you create an ifstream object, which then behaves like cin. To open a file for writing, you create an ofstream object, which then behaves like cout. Once you’ve opened the file, you can read from it or write to it just as you would with any other iostream object. It’s that simple (which is, of course, the whole point).

One of the most useful functions in the iostream library is getline( ), which allows you to read one line (terminated by a newline) into a string object[28]. The first argument is the ifstream object you’re reading from and the second argument is the string object. When the function call is finished, the string object will contain the line.

Here’s a simple example, which copies the contents of one file into another:

//: C02:Scopy.cpp
// Copy one file to another, a line at a time
#include <string>
#include <fstream>
using namespace std;

int main() {
  ifstream in("Scopy.cpp"); // Open for reading
  ofstream out("Scopy2.cpp"); // Open for writing
  string s;
  while(getline(in, s)) // Discards newline char
    out << s << "\n"; // ... must add it back
} ///:~

To open the files, you just hand the ifstream and ofstream objects the file names you want to create, as seen above.

There is a new concept introduced here, which is the while loop. Although this will be explained in detail in the next chapter, the basic idea is that the expression in parentheses following the while controls the execution of the subsequent statement (which can also be multiple statements, wrapped inside curly braces). As long as the expression in parentheses (in this case, getline(in, s)) produces a “true” result, then the statement controlled by the while will continue to execute. It turns out that getline( ) will return a value that can be interpreted as “true” if another line has been read successfully, and “false” upon reaching the end of the input. Thus, the above while loop reads every line in the input file and sends each line to the output file.

getline( ) reads in the characters of each line until it discovers a newline (the termination character can be changed, but that won’t be an issue until the iostreams chapter in Volume 2). However, it discards the newline and doesn’t store it in the resulting string object. Thus, if we want the copied file to look just like the source file, we must add the newline back in, as shown.

Another interesting example is to copy the entire file into a single string object:

//: C02:FillString.cpp
// Read an entire file into a single string
#include <string>
#include <iostream>
#include <fstream>
using namespace std;

int main() {
  ifstream in("FillString.cpp");
  string s, line;
  while(getline(in, line))
    s += line + "\n";
  cout << s;
} ///:~

Because of the dynamic nature of strings, you don’t have to worry about how much storage to allocate for a string; you can just keep adding things and the string will keep expanding to hold whatever you put into it.

One of the nice things about putting an entire file into a string is that the string class has many functions for searching and manipulation that would then allow you to modify the file as a single string. However, this has its limitations. For one thing, it is often convenient to treat a file as a collection of lines instead of just a big blob of text. For example, if you want to add line numbering it’s much easier if you have each line as a separate string object. To accomplish this, we’ll need another approach.

Thinking in C++
Prev Contents / Index Next

 
 
   Reproduced courtesy of Bruce Eckel, MindView, Inc. Design by Interspire