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" ); |
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步