Input and Output File

Notes from C++ Primer

 

File State

Condition state is used to manage stream state, which indicates if the stream is available or recoverable.

State of stream is descripted by three member function: bad, fail, eof and good.

  • bad(): unrecoverable error. If the stream state is badbit, then it can't be used again. bad() returns true.
  • fail(): recoverable error. If the stream state is failbit, fail() returns true.
  • eof(): when stream meets the end-of-file. eofbit will be set. Also, the stream will be set failbit at the same time.
  • good(): the state of stream. If one of bad, fail, eof  is true, the good will return false, otherwise return true.

There're two operations to change the condition state: clear, setstate.

  • clear: reset the stream to be available.
  • setstate: open one of specified condition state.

 

The mangement of stream can be like this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
int ival;
 
// read cin and test only for EOF; loop is executed even if there are other IO failures
while(cin >> word, !cin.eof())
{
    if(cin.bad())                                                           // input stream is corrupted; bail out
        throw runtime_error("IO stream corrupted");
     
    if(cin.fail())                                                          // bad input
    {
        cerr << "bad data, try again";                                  // warn the user
        cin.clear(istream::failbit);                                    // reset the stream
        continue;
    }
     
    // ok to process ival
    ...
}

 

Member function rdstate() returns the current state of stream. The below example also display how to set the state of stream:

1
2
3
4
5
6
7
8
9
10
11
12
// remember current state of cin
istream::iostate old_state = cin.rdstate();
 
cin.clear();
process_input();         // use cin
 
cin.clear(old_state);    // now reset cin to old state
 
...
 
// sets both the badbit and the failbit
is.setstate(ifstream::badbit | ifstream::failbit);

 

 

 

Use of File Stream

Assume ifle and ofile is the string object storing the names of input and output files' namess.

1
2
string ifile = "inputFile.txt";
string ofile = "outputFile.txt";

 Then the use of file stream is like this:

1
2
3
4
// construct an ifstream and bind it to the file named ifile
ifstream infile(ifile.c_str());
// ofstream output file object to write file named ofile
ofstream outfile(ofile.c_str());

 

Also, we can define unbound input and output file stream first, and then use open function to boud the file we'll access:

1
2
3
4
5
ifstream infile;                // unbound input file stream
ofstream outfile;               // unbound output file stream
 
infile.open("in");              // open file named "in" in the current directory
outfile.open("out");            // open file named "out" in the current directory

 

After opening the file, we need to check if it is successful being opened: 

1
2
3
4
5
6
7
// check that the open succeeded
if(!infile){
    cerr << "error: unable to open input file: "
         << infile << endl;
     
    return -1;
}

 

Rebound File Stream with New File

If we want to bound the fstream with another file, we need to close the current file first, and then bound with another file:

1
2
3
ifstream infile("in");          // open file named "in" for reading
infile.close();                 // closes "in"
infile.open("next");            // open file named "next" for reading

 

Clear File Stream Status

Opening all file names in a string vector, one direct version is:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
vector<string> files;
...
vector<string>::const_iterator it = files.begin();
string s;                                                     // string buffer
 
// for each file in the vector
while(it != files.end()){
    ifstream input(it->c_str());                          // open the file
     
    // if the file is ok, read and "process" the input
    if(!input)
        break;                                        // error: bail out!
    while(input >> s)                                     // do the work on this file
        process(s);
    ++it;                                                 // increament iterator to get next file
}

 

More efficient way but with much more accurate operation version:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
ifstream input;
vector<string>::const_iterator it = files.begin();
 
// for each file in the vector
while(it != files.end()){
    input.open(it->c_str());                                   // open the file
     
    // if the file is ok, read and "process" the input
    if(!input)
        break;                                             // error: bail out!
    while(input >> s)                                          // do the work on this file
        process(s);
     
    input.close();                                             // close file when we're done with it
    input.clear();                                             // reset state to ok
    ++it;
}

 

File Mode

When you use ofstream to open file, the only way to store existing data is to set the app mode explicitly.

1
2
3
4
5
6
7
8
// output mode by default; truncates file named "file1"
ofstream outfile("file1");
 
// equivalent effect: "file1" is explicitly truncated
ofstream oufile2("file1", ofstream::out | ofstream::trunc);
 
// append mode: adds new data at end of existing file named "file2"
ofstream appfile("file2", ofstream::app);

 

File mode is the attribute of file, not stream

1
2
3
4
5
6
7
8
9
10
11
ofstream outfile;
// output mode set to out, "scratchpad" truncated because of after definition
outfile.open("scratchpad", ofstream::out);
outfile.close();    // close outfile so we can rebind it
 
// appends to file named "precious"
outfile.open("precious", ofstream::app);
outfile.close();
 
// output mode set by default, "out" truncated
outfile.open("out");

 

posted @   kid551  阅读(322)  评论(0编辑  收藏  举报
努力加载评论中...
点击右上角即可分享
微信分享提示