幾乎所有的內容都從 “Data Structure and Programming Prof. Chung-Yang (Ric) Huang” 取得
Formatted und Unformatted
Unformatted I/O (Low-level)
- get, getline, put, read, write…
- high-speed, high-volume
- may have portability problem
Formatted I/O (High-level)
- operators “<<“ and “>>”, I/O manipulators
- bytes are grouped into meaningful units (e.g. integer, float and character…), and sensitive to data types
- If unexpected data is processed, error bits are set
ostream& operator <<
Does not print out until ‘\n” or “flush()” is calledistream& operator >>
Stop at white space, but not process until ‘\n’ is entered
Unformatted I/O operation
istream::get
single character | int get(); istream& get (char& c); |
---|---|
c-string | istream& get (char* s, streamsize n); istream& get (char* s, streamsize n, char delim); |
stream buffer | istream& get (streambuf& sb); istream& get (streambuf& sb, char delim); |
Delimiter is left in the stream, not placed in array.
Won’t process if char in stream is not enough for “streamsize”
istream::getline
istream& getline (char* s, streamsize n );
istream& getline (char* s, streamsize n, char delim );
Their has another function std::getline (string)
Delimiter is removed from the stream, and not placed in the array
istream::read
istream& read (char* s, streamsize n);
This function simply copies a block of data, without checking its contents nor appending a null character at the end.
istream::gcount
number of characters extracted by the last unformatted input operation
(e.g. get, getline, ignore, peek, read, readsome, putback and unget.)
ostream::put
ostream& put (char c);
Returns a reference to the same ostream object
ostream::write
ostream& write (const char* s, streamsize n);
This function simply copies a block of data, without checking its contents: The array may contain null characters, which are also copied without stopping the copying process.
I/O Stream Manipulators
Manipulators
dec, endl, ends, flush, hex, oct, left, right, ws, setbase(n), setw(n), setioflags(i), resetioflags(i), setfill(c), setprecision(n)
Sticky und non-sticky
“Sticky”: Not across to another object of the same stream class, or any other object of other stream classes
Most IO manipulators are “sticky”
Exception: Field width
- setw(int) // c.f. “width()” member function
- For both istream (input size) and ostream (display size)
I/O Stream Printing Format
- Type fmtflags is of class ios_base
- Initial return value may differ across platforms
#include <iostream> #include <fstream> #include <iomanip> using namespace std; int main() { int i = 100; ofstream outf("ttt"); outf << showbase << hex << i << endl; // 0x64 ios_base::fmtflags origFlags = outf.flags(); outf.close(); ifstream inf("ttt"); inf.flags(origFlags); inf >> i; cout << setw(10) << right << i << endl; // 100 return 0; }
User-Defined
class Myclass { friend ostream& operator << (ostream& os, const Myclass& e); int data; }; ostream& operator << (ostream& os, const Myclass& e) { os << e.data; return os; } int main() { Myclass m; cout << m << endl; }
State Bits
- failbit
- Set if input data is of wrong type (format error)
- Data still remains in stream buffer
- badbit
- Set if stream extraction operation fails (more serious)
- eofbit
- Set if the end of file is reached during stream input
- 先把 eof 吃進去之後才會觸發,小心不要多跑一次
- goodbit
- ! (failbit | badbit | eofbit)
Functions
- bool fail(), bad(), eof(), good()
- eofbit set to true after read in eof
- rdstate()
- read state bits
- clear(iostate state = ios::goodbit)
- clear cin and set iostate
- default argument is set state as goodbit
#include <iostream> #include <string> int main() { double n; while( std::cout << "Please, enter a number\n" && ! (std::cin >> n) ) { std::cin.clear(); std::string line; std::getline(std::cin, line); std::cout << "I am sorry, but '" << line << "' is not a number\n"; } std::cout << "Thank you for entering the number " << n << '\n'; }
std::basic_ios::operator bool (link)
operator void*() const; | (until C++11) |
explicit operator bool() const; | (since C++11) |
- static_cast<bool>(cin)
- while(cin >> n)
- operator void*() type-casting, converted to void*
- A a; void *p = a;
- void* operator() () operator overloading, function object
- A a; void *p = a();

Sync
std::ios::tie
ostream* tie() const; // get
ostream* tie (ostream* tiestr); // set and get the old one
當一個 istream 跟 ostream 綁在一起時,c++就會確保這兩個stream動作的順序是正確的,也就是說會在 “>>” 之類的等待輸入之前,先把ostream的buffer清空並輸出。
c++一開始會自動做 cin.tie( &cout );
,所以之前有時候在寫online judge時會先 cin.tie(null)
取消綁定,反正oj的輸入輸出順序不影響評分嘛。
另外這個函數回傳的就是該 istream 綁定的 ostream 的 pointer ,例如沒有去做變更tie的cin的*(cin.tie())
就是cout
喔。
std::ios_base::sync_with_stdio(false)
默認情況下 c++ stream 會跟 c stream 同步,但這樣會讓cin/cout變得很慢,所以當你不會直接用到 c 的library時,就把這個功能關掉吧
seek/tell
c++的istream維護一個input指針(seekg/tellg),而ostream則維護output指針(seekp/tellp)
istream::seekg
istream::tellg
istream& seekg (streampos pos); // 設絕對位置
istream& seekg (streamoff off, ios_base::seekdir way); // 設相對位置, 參考點
streampos tellg()
Calling this function does not alter the value returned by gcount.
seekdir
- ios::beg – default, position relative to the beginning
- ios::cur – relative to current position
- ios::end – relative to the end
buffer
ios::rdbuf()
streambuf* rdbuf() const; // get
streambuf* rdbuf (streambuf* sb); // set
If sb is a null pointer, the function automatically sets the badbit error state flags (which may throw an exception if member exceptions has been passed badbit).
#include <iostream> #include <sstream> using namespace std; int main () { stringstream ss; streambuf *backup = cout.rdbuf(); streambuf *psbuf = ss.rdbuf(); ss << "Let me write something beforehand…" << endl; cout.rdbuf(psbuf); cout << "This is written to stringstream\n"; cout.rdbuf(backup); cout << "Hello!!" << endl; cout << ss.str() << endl; }
Random-Access Files
#include <iostream> #include <fstream> using namespace std; class StudentRecord { friend istream& operator >> (istream& is, StudentRecord& e); friend ostream& operator << (ostream& os, const StudentRecord& e); private: string _id; string _name; }; istream& operator >> (istream& is, StudentRecord& e){ return (is >> e._id >> e._name); } ostream& operator << (ostream& os, const StudentRecord& e){ return (os << e._id << " " << e._name); } int main() { StudentRecord rec; ofstream outf("studentRecord.dat"); cin >> rec; outf.write(reinterpret_cast<const char *>(&rec), sizeof(StudentRecord)); outf.close(); cout << rec << endl; rec = StudentRecord(); cout << rec << endl; ifstream inf("studentRecord.dat"); inf.read(reinterpret_cast<char *>(&rec), sizeof(StudentRecord)); cout << rec << endl; }
00000000: 90cd eadf ff7f 0000 0900 0000 0000 0000 ................ 00000010: 6230 3736 3131 3031 3200 eadf ff7f 0000 b07611012....... 00000020: b0cd eadf ff7f 0000 0600 0000 0000 0000 ................ 00000030: 616e 6472 6577 0000 0a77 bac9 517f 0000 andrew...w..Q...