C++学习手记五:C++流操作
為什么80%的碼農(nóng)都做不了架構(gòu)師?>>> ??
寫在前面:
說到流操作,則與程序的輸入輸出(簡記為I/O)有關(guān),本文講述C++的一些I/O操作。本文所用的一些操作雖然都是基于標(biāo)準(zhǔn)輸入輸出(如屏幕和鍵盤到程序的輸出和輸入),但是這些規(guī)則對于接下來的文件操作也是有用的。C++ I/O 區(qū)分流的種類,特定種類的I/O只能處理特定數(shù)據(jù)類型的流,稱作種類安全流機(jī)制(Type-safe IO)(Chap 13 13.1 p.g.416)
C++含有變量wchar_t,用來表示Unicode字符;char16_t和char32_t是分別限定Unicode大小的字符變量種類。(Chap 13 13.2 p.g.418)
幾個(gè)常用的有關(guān)流操作的頭文件: <iostream>:定義基本I/O對象,例如cin, cout, cerr(非緩沖流,立即被輸出到輸出設(shè)備)和clog <iomanip>:提供格式化流操作 <fstream>:用于文件處理的流操作(本章不涉及,在文件操作時(shí)會再提)
在流文件中,存在如下定義:
//在流編程中一般直接使用typedef定義的名稱 typedef basic_istream<char> istream; typedef basic_ostream<char> ostream; typedef basic_iostream<char> iostream;關(guān)于typedef參考: https://my.oschina.net/SamYjy/blog/912868
C++流結(jié)構(gòu)圖示如下:
關(guān)于void *的兩個(gè)作用:
void *用于輸出字符指針的地址
由于C++自動決定數(shù)據(jù)的類型,因此當(dāng)碰到諸如輸出char *的值(指針的值是地址)的情況時(shí),就需要把指針轉(zhuǎn)化為空指針再進(jìn)行輸出,例如:
#include <cstdlib> #include <iostream>using namespace std;int main(int argc, char** argv) {const char *const words = "This is a sentence.";int num = 7;const int * const numPtr = #//輸出char*的值所對應(yīng)的內(nèi)容:cout << "Content of words is: " << words << endl;cout << "Content of numPtr is: " << *numPtr << endl;//輸出char*的值(是一個(gè)地址):cout << "Value of words is: " << static_cast< const void * >( words ) << endl;cout << "Value of numPtr is: " << numPtr << endl;cout << "Value of numPtr is: " << static_cast< const void * >( numPtr ) << endl;return 0; }- put方法:輸出單個(gè)字符串,可以層疊,用法例如:
void *被隱式調(diào)用用于判定輸入是否結(jié)束:
此時(shí),void *往往被cin.get()方法隱式調(diào)用,以判斷輸入是否完成。例如:
//EOF為cin.get()隱式調(diào)用void *之后文件結(jié)束的返回值while ( ( character = cin.get() ) != EOF )cout.put( character );其中,cin.get有5個(gè)不同類型的版本。詳細(xì)見參考資料相應(yīng)部分。此方法默認(rèn)輸入不固定長度,并且以空格符號為界定符,將輸入賦值給指定char *變量。使用舉例如下:
#include <iostream>using namespace std;int main() {// create two char arrays, each with 80 elementsconst int SIZE = 80;char buffer1[ SIZE ];char buffer2[ SIZE ];char buffer3[ SIZE ];// use cin to input characters into buffer1cout << "Enter a sentence:" << endl;cin >> buffer1;// display buffer1 contentscout << "\nBuffer 1:" << buffer1 << endl;// use cin.get to input characters into buffer2cin.get( buffer2, SIZE, 'l' ); //如果界定符前一個(gè)字符是r,將字母r放回流中cin.putback('r');// display buffer2 contentscout << "Buffer 2:" << buffer2 << endl;int nextChar = cin.peek();cout << "Next char will be output is: " << (char)(nextChar) << endl; /*使用如下兩種方法可以清除流中不需要的多余數(shù)據(jù):*///方法一://int input;//while(input = cin.get() != '\n')//By default, ignore method ignores 1 char only//cin.ignore(1); //此處可以不寫1//方法二://fflush(stdin);cin.get( buffer3, SIZE );cout << "Buffer 3: " << buffer3 << endl; } // end main用于處理非格式化I/O的方法:read, write和gcount:
對于非格式化流,C++使用read函數(shù)向程序讀入數(shù)據(jù),使用write函數(shù)向輸出(可能是屏幕或硬盤)寫出數(shù)據(jù),使用gcount統(tǒng)計(jì)上一個(gè)輸入流的字符長度(輸入不滿char[] 大小時(shí)按實(shí)際輸入長度確定)。舉例如下:
#include <iostream> using namespace std;int main() {const int SIZE = 80;char buffer[ SIZE ]; // create array of 80 characters// use function read to input characters into buffercout << "Enter a sentence:" << endl;cin.read( buffer, 20 );cout << "Length of last in stream: " << cin.gcount() << endl;// use functions write and gcount to display buffer characterscout << endl << "The sentence entered was:" << endl;cout.write( buffer, cin.gcount() );cout << endl; } // end main流操作符簡介
常用流函數(shù):
- setbase(int):設(shè)置輸出數(shù)據(jù)的基數(shù),此整數(shù)可以為2,8,10或16
- setprecision(int) / cout.setprecision(int):設(shè)置輸出小數(shù)的精度
- setw(int) / cout.width(int) / cin.width(int):設(shè)置輸出/輸入的字符最大長度,輸出超過最大長度的,則按照字符長度輸出整個(gè)字符;而輸入則最多讀入最大長度的字符。詳細(xì)情況見以下示例程序。
- setfill(char) / cout.fill(char) :往往與setw搭配使用,在多余的空格處填充相應(yīng)字符。
常用流操作常量一覽:
示例程序:
#include <iostream> #include <iomanip>using namespace std;int main() {int widthValue = 4;char sentence[ 10 ];cout << "Enter a sentence:" << endl;cin.width( 6 ); // input only 5 characters from sentencecout << setfill('*');//or can be://cout.fill('*');// set field width, then display characters based on that width while ( cin >> sentence ) {cout << setw(widthValue ++);cout << sentence << endl;cout << "Length of output: " << oct << showbase << widthValue << endl;//Can also be://cout.width( widthValue++ ); cin.width(6);//Or can be: //cin >> setw( 6 ); // input 5 more characters from sentence} // end while } // end main輸出解釋:cin默認(rèn)情況相當(dāng)于cin.get(),碰到界定符為空格時(shí)停止從流中讀入數(shù)據(jù),并將空格符號作為下一次讀入的第一個(gè)字符。由于單詞member前五個(gè)字母以及它之前一個(gè)空格正好構(gòu)成6個(gè)字符,達(dá)到了輸入流限制的最大長度,因此字母r作為下一個(gè)輸入流的起始被讀入。同理可分析function的讀入情況。
C++中,可以通過在程序運(yùn)行前儲存程序當(dāng)前流操作符號狀態(tài),使用完畢后恢復(fù)的方式來避免粘性流操作符對于之后程序產(chǎn)生的可能影響,具體程序如下:
//儲存當(dāng)前流操作符狀態(tài): ios_base::fmtflags originalFormat = cout.flags();//省略中間部分可能改變流操作符狀態(tài)的部分 //......//恢復(fù)到原來的流操作符狀態(tài): cout.flags(originalFormat);C++中,可以通過cin.clear()使得輸入流恢復(fù)到一個(gè)正常流的狀態(tài),限于篇幅,這一點(diǎn)本文不展開,詳見參考資料(C++11 Chap 13.8 p.g.442)
在C++中,標(biāo)準(zhǔn)輸入流往往總是在其相應(yīng)輸出流之后出現(xiàn),目的是便于向用戶提供交互信息后再采納用戶輸入。對于其他一般的流,則可以通過
input.tie(&output);的方式指定相應(yīng)流運(yùn)行的順序。取消這樣的順序限定,可以使用
input.tie(0);實(shí)現(xiàn)。
參考資料:
轉(zhuǎn)載于:https://my.oschina.net/Samyan/blog/1204687
總結(jié)
以上是生活随笔為你收集整理的C++学习手记五:C++流操作的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: JAVA RTTI
- 下一篇: 在Visual Studio 2010/