Hi!这里是山幺幺的c++ primer系列。写这个系列的初衷是,虽然在学校学习了c++,但总觉得对这门语言了解不深,因此我想来啃啃著名的c++ primer,并在这里同步记录我的学习笔记。由于我啃的是英文版,所以笔记是中英文夹杂的那种。另外由于已有一定的编程基础,所以这个系列不会含有太基础的知识,想入门的朋友最好自己啃书嘻嘻~
I/O Classes
I/O library types
PS:w开头的类:To support languages that use wide characters, the library defines a set of types and objects that manipulate wchar_t data
- ifstream and istringstream inherit from istream
- ofstream and ostringstream inherit from ostream
I/O Objects的限制
- No Copy or Assign for I/O Objects,因此parameter or return type都不能是I/O type
- reading or writing an I/O object changes its state, so the reference to I/O objects must not be const
I/O Library Condition State
- I/O objects will be in an error state if 输入的对象类型与期待的类型不匹配等
- Once an error has occurred, subsequent IO operations on that stream will fail. We can read from or write to a stream only when it is in a non-error state.
- The IO library defines a machine-dependent integral type named iostate,该类型有四个值:
- badbit:indicates a system-level failure, such as an unrecoverable read or write error.
- failbit:is set after a recoverable error, such as reading a character when numeric data was expected.
- eofbit:reaching end-of -file sets both eofbit and failbit.
- goodbit:guaranteed to have the value 0, indicates no failures on the stream.
PS:If any of badbit, failbit, or eofbit are set, then a condition that evaluates that stream will fail.
- 栗子
// turns off failbit and badbit but all other bits unchanged
cin.clear(cin.rdstate() & ~cin.failbit & ~cin.badbit);
output buffer
buffer的作用:Using a buffer allows the operating system to combine several output operations from our program into a single system-level write,从而提升性能
-
flush buffer(即buffer中内容全部输出)的时机:
- The program completes normally. All output buffers are flushed as part of the return from main
- buffer满了之后will be flushed before writing the next value
- We can flush the buffer explicitly using a manipulator
cout << "hi!" << endl; // writes hi and a newline, then flushes the buffer cout << "hi!" << flush; // writes hi, then flushes the buffer; adds no data cout << "hi!" << ends; // writes hi and a null, then flushes the buffer
- 可以用unitbuf把stream的state设置为empty the buffer after each output operation:By default, unitbuf is set for cerr, so that writes to cerr are flushed immediately
cout << unitbuf; // all writes will be flushed immediately cout << nounitbuf; // returns to normal buffering
- the buffer of the tied stream is flushed whenever the tied stream is read or written.
- By default, cin and cerr are both tied to cout. Hence, reading cin or writing to cerr flushes the buffer in cout.
cin >> ival; // causes the buffer associated with cout to be flushed.
- We can tie either an istream or an ostream object to another ostream;一个istream/ostream只能 be tied to 一个ostream
ostream *p = cin.tie(); // p points to the stream (if any) currently tied to cin, 若无则p = nullptr cin.tie(&cout); // illustration only: the library ties cin and cout for us // old_tie points to the stream (if any) currently tied to cin ostream *old_tie = cin.tie(nullptr); // cin is no longer tied cin.tie(&cerr); // reading cin flushes cerr, not cout cin.tie(old_tie); // reestablish normal tie between cin and cout
PS:Output buffers are not flushed if the program terminates abnormally.
文件I/O
file I/O types
- ifstream:read from a given file
- ofstream:write to a given file
- fstream:reads and writes a given file
PS:这些类型继承了iostream types的操作,比如<< >> getline等;所有可以使用iostream types的地方都可以使用对应的file I/O types
fstream-Specific Operations
- 除了从iostream继承的操作,file I/O types还支持以下操作:
定义file I/O对象
- 栗子(filename可以是string or C-style character array)
ifstream in(ifile); // construct an ifstream and open the given file
ofstream out; // output file stream that is not associated with any file
open和close
-
open
- 用法
ofstream out; // output file stream that is not associated with any file out.open(ifile + ".copy"); // open the specified file if (out) { ... }
- Once a file stream has been opened, it remains associated with the specified file
- calling open on a file stream that is already open will fail and set failbit
-
close
- 用法
in.close(); // close the file in.open(ifile + "2"); // open another file
- To associate a file stream with a different file, we must first close the existing file. Once the file is closed, we can open a new one
- When an fstream object is destroyed, close is called automatically
File Mode
- out may be set only for an ofstream or fstream object
- in may be set only for an ifstream or fstream object
- trunc may be set only when out is also specified
- app mode may be specified so long as trunc is not. If app is specified, the file is always opened in output mode, even if out was not explicitly specified
- By default, a file opened in out mode is truncated even if we do not specify
trunc. By default, when we open an ofstream, the contents of the file are discarded - To preserve the contents of a file opened with out, either we must also specify app, in which case we can write only at the end of the file, or we must also specify in, in which case the file is open for both input and output
- The ate and binary modes may be specified on any file stream object type
and in combination with any other file modes - 默认模式:Files associated with an ifstream are opened in in mode; files associated with an ofstream are opened in out mode; and files associated with an fstream are opened with both in and out modes
- 栗子
// file1 is truncated in each of these cases
ofstream out("file1"); // out and trunc are implicit
ofstream out2("file1", ofstream::out); // trunc is implicit
ofstream out3("file1", ofstream::out | ofstream::trunc);
// to preserve the file's contents, we must explicitly specify app mode
ofstream app("file2", ofstream::app); // out is implicit
ofstream app2("file2", ofstream::out | ofstream::app);
string Streams
特点
- in-memory IO
- read from or write to a string as if the string were an IO stream
类型
- istringstream:reads a string
- ostringstream:writes a string
- stringstream:reads and writes the string
PS:这些类型继承了iostream types的操作,比如<< >> getline等;所有可以使用iostream types的地方都可以使用对应的string streams types
sstream-Specific Operations
- 除了从iostream继承的操作,string streams types还支持以下操作:
栗子
- istringstream
要读的文件如下
morgan 2015552368 8625550123
drew 9735550130
lee 6095550132 2015550175 8005550000
struct PersonInfo {
string name;
vector<string> phones;
};
string line, word;
vector<PersonInfo> people; // will hold all the records from the input
// read the input a line at a time until cin hits end-of-file (or another error)
while (getline(cin, line)) {
PersonInfo info; // create an object to hold this record's data
istringstream record(line); // bind record to the line we just read
record >> info.name; // read the name
while (record >> word) // read the phone numbers
info.phones.push_back(word); // and store them
people.push_back(info); // append this record to people
}
- ostringstream
for (const auto &entry : people) { // for each entry in people
ostringstream formatted, badNums; // objects created on each loop
for (const auto &nums : entry.phones) { // for each number
if (!valid(nums)) {
badNums << " " << nums; // string in badNums
} else
// ''writes'' to formatted's string
formatted << " " << format(nums);
}
if (badNums.str().empty()) // there were no bad numbers
os << entry.name << " " // print the name
<< formatted.str() << endl; // and reformatted numbers
else // otherwise, print the name and bad numbers
cerr << "input error: " << entry.name
<< " invalid number(s) " << badNums.str() << endl;
}