《C++ Primer Plus》第17章:输入、输出和文件(6)
總結(jié)
流是進(jìn)出程序的字節(jié)流。緩沖區(qū)是內(nèi)存中的臨時存儲區(qū)域,是程序與文件或其他 I/O 設(shè)備之間的橋梁。信息在緩沖區(qū)和文件之間傳輸時,將使用設(shè)備(如磁盤驅(qū)動器)處理效率最高的尺寸以大塊數(shù)據(jù)的方式進(jìn)行傳輸。信息在緩沖區(qū)之間傳輸時,是逐字節(jié)傳輸?shù)?#xff0c;這種方式對于程序中的處理操作更為方便。C++ 通過將一個被緩沖流同程序及其輸入源相連來處理輸入。同樣,C++ 也通過將一個被緩沖流與程序及其輸出目標(biāo)相連來處理輸出。iostrea 和 fstream 文件構(gòu)成了 I/O 類庫,該類庫定義了大量用于管理流的類。包含了 iostream 文件的 C++ 程序?qū)⒆詣哟蜷_ 8 個流,并使用 8 個對象管理它們。cin 對象管理標(biāo)準(zhǔn)輸入流,后者默認(rèn)與標(biāo)準(zhǔn)輸入設(shè)備(通常為鍵盤)相連;cout 對象管理標(biāo)準(zhǔn)輸出流,后者默認(rèn)與標(biāo)準(zhǔn)輸出設(shè)備(通常為顯示器)相連;cerr 和 clog 對象管理與標(biāo)準(zhǔn)錯誤設(shè)備(通常為顯示器)相連的未被緩沖的流和被緩沖的流。這 4 個對象都有用于寬字符的副本,它們是 wcin、wcout、wcerr 和 wclog。
I/O 類庫提供了大量有用的方法。istream 類定義了多個版本的抽取運算符(>>),用于識別所有基本的 C++ 類型,并將字符輸入轉(zhuǎn)換為這些類型。get() 方法族和getline() 方法為單字符輸入和字符串輸入提供了進(jìn)一步的支持。同樣,ostream 類定義了多個版本的插入運算符(<<),用于識別所有的 C++ 基本類型,并將它們轉(zhuǎn)換為相應(yīng)的字符輸出。put() 方法對單字符輸出提供了進(jìn)一步的支持。wistream 和 wostream 類對寬字符提供了類似的支持。
使用 ios_base 類方法以及文件 iostream 和 iomanip 中定義的控制符(可與插入運算符拼接的函數(shù)),可以控制程序如何格式化輸出。這些方法和控制符使得能夠控制計數(shù)系統(tǒng)、字段寬度、小數(shù)位數(shù)、顯示浮點變量時采用的計數(shù)系統(tǒng)以及其他元素。
fstream 文件提供了將 iostream 方法擴(kuò)展到文件 I/O 的類定義。ifstream 類是從 istream 類派生而來的。通過將 ifstream 對象與文件關(guān)聯(lián)起來,可以使用所有的 istream 方法來讀取文件。同樣,通過將 ofstream 對象與文件關(guān)聯(lián)起來,可以使用 ostream 方法來寫文件;通過將 fstream 對象與文件關(guān)聯(lián)起來,可以將輸入和輸出方法用于文件。
要將文件與流關(guān)聯(lián)起來,可以在初始化文件流對象時提供文件名,也可以先創(chuàng)建一個文件流對象,然后用 open() 方法將這個流與文件關(guān)聯(lián)起來。close() 方法終止流與文件之間的連接。類構(gòu)造函數(shù)和open()方法接受可選的第二個參數(shù),該參數(shù)提供文件模式。文件模式?jīng)Q定文件是否被讀和/或?qū)憽⒋蜷_文件以便寫入時是否截短文件、試圖打開不存在的文件時是否會導(dǎo)致錯誤、是使用二進(jìn)制模式還是文本模式等。
文本文件以字符格式存儲所有的信息,例如,數(shù)字值將被轉(zhuǎn)換為字符表示。常規(guī)的插入和抽取運算符以及 get() 和 getline() 都支持這種模式。二進(jìn)制文件使用計算機(jī)內(nèi)部使用的二進(jìn)制表示來存儲信息。與文本文件相比,二進(jìn)制文件存儲數(shù)據(jù)(尤其是浮點值)更為精確、簡潔,但可移植性較差。read() 和 write() 方法都支持二進(jìn)制輸入和輸出。
seekg() 和 seekp() 函數(shù)提供了對文件的隨機(jī)存取。這些類方法使得能夠?qū)⑽募羔樂胖玫较鄬τ谖募_頭、文件尾和當(dāng)前位置的某個位置。tellg() 和 tellp() 方法報告當(dāng)前的文件位置。
sstream 頭文件定義了 istringstream 和 ostringstream 類,這些類使得能夠使用 istream 和 ostream 方法來抽取字符串中的信息,并對要放入到字符串中的信息進(jìn)行格式化。
復(fù)習(xí)題
istream 文件在 C++ I/O 中扮演何種角色?
答:iostream 文件定義了用于管理輸入和輸出的類、常量和操縱符,這些對象管理用于處理 I/O 的流和緩沖區(qū)。該文件還創(chuàng)建了一些標(biāo)準(zhǔn)對象(cin、cout、cerr 和 clog 以及對應(yīng)的寬字符對象),用于處理與每個程序相連的標(biāo)準(zhǔn)輸入和輸出流。
為什么鍵入數(shù)字(如121)作為輸入要求程序進(jìn)行轉(zhuǎn)換?
答:鍵盤輸入生成一系列字符。輸入121將生成3個字符,每個字符都由一個1字節(jié)的二進(jìn)制碼表示。要將這個值存儲為 int 類型,則必須將這 3 個字符轉(zhuǎn)換為 121 值的二進(jìn)制表示。
標(biāo)準(zhǔn)輸出與標(biāo)準(zhǔn)錯誤之間有什么區(qū)別?
答:在默認(rèn)情況下,標(biāo)準(zhǔn)輸出和標(biāo)準(zhǔn)錯誤都將輸出發(fā)送給標(biāo)準(zhǔn)輸出設(shè)備(通常為顯示器)。然而,如果要求操作系統(tǒng)將輸出重定向到文件,則標(biāo)準(zhǔn)輸出將與文件(而不是顯示器)相連,但標(biāo)準(zhǔn)錯誤仍與顯示器相連。
為什么在不為每個類型提供明確指示的情況下,cout 仍能夠顯示不同的 C++ 類型?
ostream 類為每種 C++ 基本類型定義了一個 operator<<() 重載。
輸出方法的定義哪一特征讓您能夠拼接輸出?
答:返回 ostream & 類型使得能夠拼接輸出。
編寫一個程序,要求用戶輸入一個整數(shù),然后以十進(jìn)制、八進(jìn)制和十六進(jìn)制顯示該整數(shù)。在寬度為 15 個字符的字段中顯示每種形式,并將它們顯示在同一行上,同時使用 C++ 基數(shù)前綴。
#include<iostream> #include<iomanip>int main() {int num;std::cout << "Input an integer: ";std::cin >> num;std::cout.setf(std::ios_base::showbase);std::cout << std::hex << std::setw(15) << num<< std::dec << std::setw(15) << num<< std::oct << std::setw(15) << num << std::endl;return 0; }編寫一個程序,請求用戶輸入下面的信息,并按下面的格式顯示它們:
Enter your name: Billy Gruff Enter your hourly wages: 12 Enter number of hours worked: 7.5 Fisrt format:Billy Gruff: $ 12.00: 7.5 Second format: Billy Gruff : $12.00 :7.5答:
#include<iostream> #include<iomanip>const int LIM = 20;int main() {using namespace std;char name[20];float hourly;float hours;cout << "Enter your name: ";cin.get(name, LIM).get();cout << "Enter your hourly wages: ";cin >> hourly;cout << "Enter number of hours worked: ";cin >> hours;cout.setf(ios::showpoint);cout.setf(ios::fixed, ios_base::floatfield);cout << "Fisrt format:\n";cout.setf(ios_base::right, ios_base::adjustfield);cout << setw(20) << name << ": $" << setprecision(2)<< setw(10) << hourly << ":" << setprecision(1)<< setw(5) << hours << "\n";cout << "Second format:\n";cout.setf(ios_base::left, ios_base::adjustfield);cout << setw(20) << name << ": $" << setprecision(2)<< setw(10) << hourly << ":" << setprecision(1)<< setw(5) << hours << "\n";return 0;}對于下面的程序:
rq17-8.cpp #include <iostream> #include <iomanip>int main() {using namespace std;char ch;int ct1 = 0;cin >> ch;while ( ch != 'q' ) {ct1++;cin >> ch;}int ct2 = 0;cin.get(ch);while ( ch != 'q' ) {ct2++;cin.get(ch);}cout << "ct1 = " << ct1 << "; ct2 = " << ct2 << "\n";return 0; }如果輸入如下,該程序?qū)⒋蛴∈裁磧?nèi)容?
I see a q<Enter> I see a q<Enter>答:
ct1 = 5; ct2 = 9;
該程序的前半部分忽略空格和換行符,而后半部分沒有。注意,程序的后半部分從第一個 q 后面的換行符開始讀取,將換行符計算在內(nèi)。
下面的兩條語句都讀取并丟棄行尾之前的所有字符(包括行尾)。這兩條語句的行為在哪方面不同?
while (cin.get() != '\n') {continue; } cin.ignore(80, '\n');答:第一條語句可以除去包括換行符在內(nèi)的該行的所有字符,而第二條語句雖然也能這樣做,但最多只能去除80個字符,如果在清除了80個字符時仍然沒有遇到換行符,就將剩下的字符留在緩沖區(qū)。
總結(jié)
以上是生活随笔為你收集整理的《C++ Primer Plus》第17章:输入、输出和文件(6)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 阿里云ACP备考分享及刷题总结
- 下一篇: VC++修改DNS