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