1. 程式人生 > >Just Do It

Just Do It


1.ios類中的列舉常量
在根基類ios中定義有三個使用者需要使用的列舉型別,由於它們是在公用成員部分定義的,所以其中的每個列舉型別常量在加上ios::字首後都可以為本類成員函式和所有外部函式訪問。在三個列舉型別中有一個無名列舉型別,其中定義的每個列舉常量都是用於設定控制輸入輸出格式的標誌使用的。該列舉型別定義如下:
enum {skipws, left, right, internal, dec, oct, hex, showbase, 
showpoint, uppercase, showpos, scientific, fixed, unitbuf, stdio
};
各列舉常量的含義如下:
skipws 
利用它設定對應標誌後,從流中輸入資料時跳過當前位置及後面的所有連續的空白字元,從第一個非空白字元起讀數,否則不跳過空白字元。空格、製表符'/t'、回車符'/r'和換行符'/n'統稱為空白符。預設為設定。
left, right, internal
left在指定的域寬內按左對齊輸出,right按右對齊輸出,而internal使數值的符號按左對齊、數值本身按右對齊輸出。域寬內剩餘的字元位置用填充符填充。預設為right設定。在任一時刻只有一種有效。
dec, oct, hex 
設定dec對應標誌後,使以後的數值按十進位制輸出,設定oct後按八進位制輸出,而設定hex後則按十六進位制輸出。預設為dec設定。
showbase 
設定對應標誌後使數值輸出的前面加上"基指示符",八進位制數的基指示符為數字0,十六進位制數的基指示符為0x,十進位制數沒有基指示符。預設為不設定,即在數值輸出的前面不加基指示符。
showpoint 
強制輸出的浮點數中帶有小數點和小數尾部的無效數字0。預設為不設定。
uppercase 
使輸出的十六進位制數和浮點數中使用的字母為大寫。預設為不設定。即輸出的十六進位制數和浮點數中使用的字母為小寫。
showpos 
使輸出的正數前帶有正號"+"。預設為不設定。即輸出的正數前不帶任何符號。
scientific, fixed 
進行scientific設定後使浮點數按科學表示法輸出,進行fixed設定後使浮點數按定點表示法輸出。只能任設其一。預設時由系統根據輸出的數值選用合適的表示輸出。
unitbuf, stdio 
這兩個常量很少使用,所以不予介紹。
在ios中定義的第二個列舉型別為:
enum open_mode {in, out, ate, app, trunc, nocreate, noreplace, binany};
其中的每個列舉常量規定一種檔案開啟的方式,在定義檔案流物件和開啟檔案時使用。
在ios中定義的第三個列舉型別為:
enum seek_dir {beg, cur, end};
其中的每個列舉常量用於對檔案指標的定位操作上。

2. ios類中的成員函式
ios類提供成員函式對流的狀態進行檢測和進行輸入輸出格式控制等操作,每個成員函式的宣告格式和簡要說明如下: 
int bad(); //操作出錯時返回非0值。
int eof(); //讀取到流中最後的檔案結束符時返回非0值。
int fail(); //操作失敗時返回非0值。
void clear(); //清除bad,eof和fail所對應的標誌狀態,使之恢復為正常狀態
//值0,使good標誌狀態恢復為1。
char fill(); //返回當前使用的填充字元。
char fill(char c); //重新設定流中用於輸出資料的填充字元為c的值,返回此
//前的填充字元。系統預設定填充字元為空格。
long flags(); //返回當前用於I/O控制的格式狀態字。
long flags(long f); //重新設定格式狀態字為f的值,返回此前的格式狀態字。
int good(); //操作正常時返回非0值,當操作出錯、失敗和讀到檔案結束符時
//均為不正常,則返回0。
int precision(); //返回浮點數輸出精度,即輸出的有效數字的位數。
int precision(int n); //設定浮點數的輸出精度為n,返回此前的輸出精度。
//系統預設定的輸出精度為6,即輸出的浮點數最多
//具有6位為有效數字。
int rdstate(); //操作正常時返回0,否則返回非0值,它與good()正好相反。
long setf(long f); //根據引數f設定相應的格式化標誌,返回此前的設定。
//該引數f所對應的實參為無名列舉型別中的列舉常量(
//又稱格式化常量),可以同時使用一個或多個常量,每兩個
//常量之間要用按位或操作符連線。如當需要左對齊輸出,
//並使數值中的字母大寫時,則呼叫該函式的實參為ios::
//left | ios::uppercase。
long unsetf(long f); //根據引數f清除相應的格式化標誌,返回此前的設定。
//如要清除此前的左對齊輸出設定,恢復預設的右對齊輸出
//設定,則呼叫該函式的實參為ios::left。
int width(); //返回當前的輸出域寬。若返回數值0則表明沒有為剛才輸出的
//數值設定輸出域寬,輸出域寬是指輸出的值在流中所佔有的位元組數。
int width(int w); //設定下一個資料值的輸出域寬為w,返回為輸出上一個數
//據值所規定的域寬,若無規定則返回0。注意:此設定不
//是一直有效,而只是對下一個輸出資料有效。
因為所有I/O流類都是ios的派生類,所以它們的物件都可以呼叫ios類中的成員函式和使用ios類中的格式化常量進行輸入輸出格式控制。下面以標準輸出流物件cout為例說明輸出的格式化控制。
程式1:
#include<iostream.h>
void main()
{
int x=30, y=300, z=1024;
cout<<x<<' '<<y<<' '<<z<<endl; //按十進位制輸出
cout.setf(ios::oct); //設定為八進位制輸出
cout<<x<<' '<<y<<' '<<z<<endl; //按八進位制輸出
cout.unsetf(ios::oct); 
//取消八進位制輸出設定,恢復按十進位制輸出
cout.setf(ios::hex); //設定為十六進位制輸出
cout<<x<<' '<<y<<' '<<z<<endl; //按十六進位制輸出
cout.setf(ios::showbase | ios::uppercase);
//設定基指示符輸出和數值中的字母大寫輸出
cout<<x<<' '<<y<<' '<<z<<endl;
cout.unsetf(ios::showbase | ios::uppercase);
//取消基指示符輸出和數值中的字母大寫輸出
cout<<x<<' '<<y<<' '<<z<<endl;
cout.unsetf(ios::hex); 
//取消十六進位制輸出設定,恢復按十進位制輸出
cout<<x<<' '<<y<<' '<<z<<endl;
}
此程式的執行結果如下:
30 300 1024
36 454 2000
1e 12c 400
0X1E 0X12C 0X400
1e 12c 400
30 300 1024

程式2:
#include<iostream.h>
void main()
{
int x=468;
double y=-3.425648;
cout<<"x=";
cout.width(10); //設定輸出下一個資料的域寬為10
cout<<x; //按預設的右對齊輸出,剩餘位置填充空格字元
cout<<"y=";
cout.width(10); //設定輸出下一個資料的域寬為10
cout<<y<<endl; 
cout.setf(ios::left); //設定按左對齊輸出
cout<<"x=";
cout.width(10);
cout<<x;
cout<<"y=";
cout.width(10);
cout<<y<<endl;
cout.fill('*'); //設定填充字元為'*'
cout.precision(3); //設定浮點數輸出精度為3
cout.setf(ios::showpos); //設定正數的正號輸出
cout<<"x=";
cout.width(10);
cout<<x;
cout<<"y=";
cout.width(10);
cout<<y<<endl;
}
此程式執行結果如下:
x= 468y= -3.42565
x=468 y=-3.42565
x=+468******y=-3.43*****

程式3:
#include<iostream.h>
void main()
{
float x=25, y=-4.762;
cout<<x<<' '<<y<<endl;
cout.setf(ios::showpoint); //強制顯示小數點和無效0
cout<<x<<' '<<y<<endl;
cout.unsetf(ios::showpoint); //恢復預設輸出
cout.setf(ios::scientific); //設定按科學表示法輸出
cout<<x<<' '<<y<<endl;
cout.setf(ios::fixed); //設定按定點表示法輸出
cout<<x<<' '<<y<<endl;
}
程式執行結果如下:
25 -4.762
25.0000 -4.76200
2.500000e+001 -4.762000e+000
25 -4.762

3. 格式控制操作符
資料輸入輸出的格式控制還有更簡便的形式,就是使用系統標頭檔案iomanip.h中提供的操縱符。使用這些操縱符不需要呼叫成員函式,只要把它們作為插入操作符<<(個別作為提取操作符>>)的輸出物件即可。這些操縱符及功能如下:
dec //轉換為按十進位制輸出整數,它也是系統預置的進位制。
oct //轉換為按八進位制輸出整數。
hex //轉換為按十六進位制輸出整數。
ws //從輸入流中讀取空白字元。
endl //輸出換行符'/n'並重新整理流。重新整理流是指把流緩衝區的內容立即寫入到對
//應的物理裝置上。
ends //輸出一個空字元'/0'。
flush //只重新整理一個輸出流。
setiosflags(long f) //設定f所對應的格式化標誌,功能與setf(long f)
//成員函式相同,當然輸出該操縱符後返回的是一個
//輸出流。如採用標準輸出流cout輸出它時,則返回
//cout。對於輸出每個操縱符後也都是如此,即返回
//輸出它的流,以便向流中繼續插入下一個資料。
resetiosflags(long f) //清除f所對應的格式化標誌,功能與unsetf(long f)
//成員函式相同。當然輸出後返回一個流。
setfill(int c) //設定填充字元為ASCII碼為c的字元。
setprecision(int n) //設定浮點數的輸出精度為n。
setw(int w) //設定下一個資料的輸出域寬為w。
在上面的操縱符中,dec, oce, hex, endl, ends, flush和ws除了在iomanip.h中有定義外,在iostream.h中也有定義。所以當程式或編譯單元中只需要使用這些不帶引數的操縱符時,可以只包含iostream.h檔案,而不需要包含iomanip.h檔案。
下面以標準輸出流物件cout為例,說明使用操作符進行的輸出格式化控制。
程式4:
#include<iostream.h> 
//因iomanip.h中包含有iostream.h,所以該命令可省略
#include<iomanip.h>
void main()
{
int x=30, y=300, z=1024;
cout<<x<<' '<<y<<' '<<z<<endl; //按十進位制輸出
cout<<oct<<x<<' '<<y<<' '<<z<<endl; //按八進位制輸出
cout<<hex<<x<<' '<<y<<' '<<z<<endl; //按十六進位制輸出
cout<<setiosflags(ios::showbase | ios::uppercase);
//設定基指示符和數值中的字母大寫輸出
cout<<x<<' '<<y<<' '<<z<<endl; //仍按十六進位制輸出
cout<<resetiosflags(ios::showbase | ios::uppercase);
//取消基指示符和數值中的字母大寫輸出
cout<<x<<' '<<y<<' '<<z<<endl; //仍按十六進位制輸出
cout<<dec<<x<<' '<<y<<' '<<z<<endl; //按十進位制輸出
}
此程式的功能和執行結果都與程式1完全相同。

程式5:
#include<iostream.h>
#include<iomanip.h>
void main()
{
int x=468;
double y=-3.425648;
cout<<"x="<<setw(10)<<x;
cout<<"y="<<setw(10)<<y<<endl;
cout<<setiosflags(ios::left); //設定按左對齊輸出
cout<<"x="<<setw(10)<<x;
cout<<"y="<<setw(10)<<y<<endl;
cout<<setfill('*'); //設定填充字元為'*'
cout<<setprecision(3); //設定浮點數輸出精度為3
cout<<setiosflags(ios::showpos); //設定正數的正號輸出
cout<<"x="<<setw(10)<<x;
cout<<"y="<<setw(10)<<y<<endl;
cout<<resetiosflags(ios::left | ios::showpos);
cout<<setfill(' '); 
}
此程式的功能和執行結果完全與程式2相同。

程式6:
#include<iomanip.h>
void main()
{
float x=25, y=-4.762;
cout<<x<<' '<<y<<endl;
cout<<setiosflags(ios::showpoint);
cout<<x<<' '<<y<<endl;
cout<<resetiosflags(ios::showpoint);
cout<<setiosflags(ios::scientific);
cout<<x<<' '<<y<<endl;
cout<<setiosflags(ios::fixed);
cout<<x<<' '<<y<<endl;
}
此程式的功能和執行結果也完全與程式3相同。