Input
Input
Sometimes a program should get input from a file rather than from a user typing on a keyboard. To achieve this, a programmer can create a new input stream that comes from a file, rather than the predefined input stream
cin
that comes from the standard input (keyboard). That new input stream can then be used just likecin
, as the following program illustrates. Assume a text file exists named myfile.txt with the contents shown (created for example using Notepad on a Windows computer or using TextEdit on a Mac computer).
myfile.txt with two integers:
5
10
#include <iostream>
#include <fstream>
using namespace std;
int main() {
ifstream inFS; // Input file stream
int fileNum1 = 0; // Data value from file
int fileNum2 = 0; // Data value from file
// Try to open file
cout << "Opening file myfile.txt." << endl;
inFS.open("myfile.txt");
if (!inFS.is_open()) {
cout << "Could not open file myfile.txt." << endl;
return 1; // 1 indicates error
}
// Can now use inFS stream like cin stream
// myfile.txt should contain two integers, else problems
cout << "Reading two integers." << endl;
inFS >> fileNum1;
inFS >> fileNum2;
cout << "Closing file myfile.txt." << endl;
inFS.close(); // Done with file, so close it
// Ouput values read from file
cout << "num1: " << fileNum1 << endl;
cout << "num2: " << fileNum2 << endl;
cout << "num1 + num2: " << (fileNum1 + fileNum2) << endl;
return 0;
}
Five lines are needed for the new input stream, highlighted above. .
- The
#include <fstream>
(for "file stream") enables use of the file stream class.- A new stream variable has been declared:
ifstream inFS;
.ifstream
is short for input file stream, and is derived fromistream
.- The line
inFS.open("myfile.txt");
opens the file for reading and associates the file with theinFS
stream. Because of the high likelihood that the open fails, usually because the file does not exist or is in use by another program, the program checks whether the open was successful usingif (!inFS.is_open())
.- The successfully opened input stream can then be used just like the
cin
stream, e.g., usinginFS >> num1;
to read an integer intonum1
.- Finally, when done using the stream, the program closes the file using
inFS.close()
.- A common error is to type
cin >> num1;
when actually intending to get data from a file as ininFS >> num1
. Another common error is a mismatch between the variable data type and the file data, e.g., if the data type is int but the file data is "Hello".
The
inFS.open(str)
function has a string parameter str, which can be a C++ string or a null-terminated C string. A program often uses a user-entered string as the filename, such as usingcin >> filename;
.
/* Given
datafile.txt with two integers:
72
68
*/
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
int main() {
ifstream inFS; // Input file stream
int fileNum1 = 0; // File data
int fileNum2 = 0; // File data
string filename = ""; // Input filename
// Prompt user for filename
cout << "Enter filename: " << endl;
cin >> filename;
// Try to open file
inFS.open(filename);
if (!inFS.is_open()) {
cout << "Could not open file " << filename << endl;
return 1;
}
// Get numbers. If too few, may encounter problems
inFS >> fileNum1;
inFS >> fileNum2;
// Done with file, close it
inFS.close();
// Ouput values read from file
cout << "num1: " << fileNum1 << endl;
cout << "num2: " << fileNum2 << endl;
cout << "num1 + num2: " << (fileNum1 + fileNum2) << endl;
return 0;
}
/*
Enter filename:
datafile.txt
num1: 72
num2: 68
num1 + num2: 140
*/
A program can read varying amounts of data in a file by using a loop that reads until the end of the file has been reached, as follows. . The
eof()
function returns true if the previous stream operation reached the end of the file. Errors may be encountered while attempting to read from a file, including end-of-file, corrupt data, etc. So, a program should check that each read was successful before using the variable to which the data read was assigned. Thegood()
function returns true if the previous stream operation had no problems. Ex:if( inFS.good() ) {...}
checks that the previous read operation was successful.
/* Given:
myfile.txt with variable number of integers:
111
222
333
444
555
*/
#include <iostream>
#include <fstream>
using namespace std;
int main() {
ifstream inFS; // Input file stream
int fileNum = 0; // File data
// Open file
cout << "Opening file myfile.txt." << endl;
inFS.open("myfile.txt");
if (!inFS.is_open()) {
cout << "Could not open file myfile.txt." << endl;
return 1;
}
// Print read numbers to output
cout << "Reading and printing numbers." << endl;
while (!inFS.eof()) {
inFS >> fileNum;
if( inFS.good() ) {
cout << "num: " << fileNum << endl;
}
}
cout << "Closing file myfile.txt." << endl;
// Done with file, so close it
inFS.close();
return 0;
}
/*
Opening file myfile.txt.
Reading and printing numbers.
num: 111
num: 222
num: 333
num: 444
num: 555
Closing file myfile.txt.
*/