1. 修改顯示時的計數系統
ostream
類是從ios
類派生而來,ios
類是從ios_base
類派生而來。ios_base
類存儲了描述格式狀態的信息,例如一個類成員中某些位決定使用哪個計數系統(如八/十/十六進制),另外一個成員決定字段的寬度,且ios_base
是ostream
間接基類,因此ostream
也可以修改計數系統和字段寬度。
對于設置顯示整數的計數系統整數,我們使用dec
、hex
和oct
控制符來控制整數是以十進制、十六進制還是八進制顯示。例如:
int n = 13;
hex(cout); //控制符實際上是函數但不是成員函數,因此不必通過對象來調用,也可以使用cout < < hex;
cout < < n; //輸出d
cout < < hex;//等同hex(cout)
cout < < n; //輸出d
cout < < oct;//等同oct(cout),將輸出顯示設置為八進制
cout < < n; // 輸出15
cout < < dec < < n;//輸出13
2. 調整字段寬度
ostream
使用width()
成員函數將長度不同的數字放到寬度相同的字段中,該方法的原型如下:
int width(); //該方法返回字段寬度的當前設置
int width(int i); //該方法將字段寬度設置為i個空格,并返回以前的字段寬度值。這樣使得能夠保存以前的值,以便以后恢復寬度值使用
width()
方法只影響將顯示的下一個項目,然后字段的寬度將恢復為默認值。例如:
cout < < "字段默認寬度:" < < cout.width() < < endl;
cout < < "12345" < < endl;//顯示12345,方便查看后面每個對象顯示的時候占用的寬度
cout.width(3);//將字段寬度設置為3
cout < < 'a' < < 'b' < < 'c' < < endl;
cout.width(2);
cout < < "aaa";//測試當字節寬度設置過小,是否影響顯示,該語句執行后字符寬度將恢復為默認值0
auto i = cout.width(3);//i=0
auto j = cout.width(4);//由于上一個語句已經將寬度設置為3,因此j=3
auto k = cout.width(1);//k=4
cout < < endl;
cout < < "i = " < < i < < endl;
cout < < "j = " < < j < < endl;
cout < < "k = " < < k < < endl;
其對應的輸出為
字段默認寬度:0
12345
abc
aaa
i = 0
j = 3
k = 4
從上面的例子可以看出,將字段寬度設置為3后,字符a
顯示字符寬度為3,其余位置填充空格,且默認為右對齊。將字段寬度設置為2后,顯示字符串"aaa"
,從結果我們可以看到,字符串正常顯示,由此可以看出,cout
不會截短數據。當顯示完字符串aaa
后,我們將字符寬度設置為3,記錄上一項目的字符寬度為i
,從打印結果來看,當顯示完字符串aaa
后,寬度自動恢復為默認值0,因此i
輸出結果為0。
3. 填充字符
默認情況下,cout
使用空格填充字段中未被使用的部分,我們在1.2中的例子已經驗證過了,那填充字符可以設置嗎?答案是肯定的,使用其成員函數fill()
來改變填充字符,例如:
cout.fill('-');
cout < < "12345" < < endl;
cout.width(2);
cout < < 'a' < < 'b' < < endl;
cout.width(4);
cout < < 'a' < < 'b' < < endl;
輸出結果:
12345
-ab
---ab
由輸出結果可知,填充字符的設置與字符寬度設置不同的是,新填充的字符將一直有效,直到它更改為止。
4. 設置浮點數的顯示精度
C++的默認精度為6位(末尾的0不顯示)。cout
的precision()
成員函數可以設置顯示精度,例如:
float a = 3.1415;
float b = 0.123456789;
cout < < "a = " < < a < < endl;
cout < < "b = " < < b < < endl;
cout.precision(2);
cout < < "a = " < < a < < endl;
cout < < "b = " < < b < < endl;
輸出結果:
a = 3.1415
b = 0.123457
a = 3.1
b = 0.12
從輸出結果可以看出,precision()
也是設置一次,一直有效,直到重新設置為止。
5. setf()
C++使用setf()
成員函數控制小數點被顯示時其他幾個格式選項,其中cout.setf(std::ios_base::showpoint)
設置cout
打印浮點類型中末尾的0和小數點。例如:
float a = 13.1415;
float b = 0.123456789;
cout.setf(std::ios_base::showpoint);
cout < < "a = " < < a < < endl;
cout < < "b = " < < b < < endl;
cout.precision(2);
cout < < "a = " < < a < < endl;
cout < < "b = " < < b < < endl;
輸出結果:
a = 13.1415
b = 0.123457
a = 13.
b = 0.12
從輸出結果可以看出,setf()
也是設置一次,一直有效,直到重新設置為止。
setf()
有兩個原型,第一個為:
fmtflags setf(fmtflags); //fmtflags是bitmask類型(一種用來存儲各個位值的類型)的typedef名,用于存儲格式的標記
該版本的setf()
用來設置單個位控制的格式信息。參數是一個fmtflags
值,指出要設置哪一位。返回值的類型為fmtflags
的數字,指出所有標記以前的設置。例如要將第11位設置為1,則需要傳遞一個第11位為1的數字,返回值為原來第11位的值。ios_base
類定義了代表位值的常量,下表為其中一部分常用的定義:
【 注: 注意,僅當基數為10時才使用加號。C++將十六進制和八進制都視為無符號的,因此對它們,無需使用符號(然而,有些C++實現可能仍然會顯示加號)。】
例子:
using std::cout;
using std::endl;
using std::ios_base;
int size = 40;
int a = 63;
cout.width(size);
cout < < "cout default: a = " < < a < < endl;
cout.width(size);
cout.setf(ios_base::showpos); //顯示+
cout < < "cout.setf(ios_base::showpos): a = " < < a < < endl;
cout.width(size);
std::hex(cout); //使用hex
cout < < "std::hex(cout): a = " < < a < < endl;
cout.width(size);
cout.setf(ios_base::uppercase); // 使用大寫字母
cout < < "cout.setf(ios_base::uppercase): a = " < < a < < endl;
cout.width(size);
cout.setf(ios_base::showbase); // 使用0X前綴
cout < < "cout.setf(ios_base::showbase): a = " < < a < < endl;
cout.width(size);
cout < < "cout default: true = " < < true < < endl;
cout.width(size);
cout.setf(ios_base::boolalpha);
cout < < "cout.setf(ios_base::boolalpha): true = " < < true < < endl;
輸出結果:
cout default: a = 63
cout.setf(ios_base::showpos): a = +63
std::hex(cout): a = 3f
cout.setf(ios_base::uppercase): a = 3F
cout.setf(ios_base::showbase): a = 0X3F
cout default: true = 0X1
cout.setf(ios_base::boolalpha): true = true
第二個setf()
原型接受兩個參數,并返回以前的設置:
fmtflags setf(fmtflags, fmtflags);
第一參數和以前一樣,也是一個包含了所需設置的fmtflags
值。第二參數指出要清除第一個參數中的哪些位。例如,將第3位設置為1表示以10為基數,將第4位設置為1表示以8為基數,將第5位設置為1表示以16為基數。假設輸出是以10為基數的,而要將它設置為以16為基數,則不僅需要將第5位設置為1,還需要將第3位設置為0——這叫作清除位(clearing the bit)。使用函數setf( )
時,要做的工作多些,因為要用第二參數指出要清除哪些位,用第一參數指出要設置哪位。ios_base
類為此定義了常量(如下表所示)。
具體地說,要修改基數,可以將常量ios_base::basefield
用作第二參數,將ios_base::hex
用作第一參數。也就是說,下面的函數調用與使用十六進制控制符的作用相同:
cout.setf(ios_base::hex, ios_base::basefield); //與hex(cout);作用相同
其具體使用方法,如下例所示:
cout.setf(ios_base::left, ios_base::adjustfield);//左對齊
cout.setf(ios_base::showpos);//在正數前面加上+
cout.setf(ios_base::showpoint);//顯示小數點和末尾的0
cout.precision(3);
//使用科學計數法顯示,并保存默認的計數法
ios_base::fmtflags old =
cout.setf(ios_base::scientific, ios_base::floatfield);
cout < < "Left Justification:n";
long n;
for (n = 1; n <= 41; n += 10) {
cout.width(4);
cout < < n < < "|";
cout.width(12);
cout < < sqrt(double(n)) < < "|n";
}
cout.setf(ios_base::internal, ios_base::adjustfield);//居中對齊
//恢復默認計數法
cout.setf(old, ios_base::floatfield);
cout < < "Internal Justification:n";
for (n = 1; n <= 41; n += 10) {
cout.width(4);
cout < < n < < "|";
cout.width(12);
cout < < sqrt(double(n)) < < "|n";
}
cout.setf(ios_base::right, ios_base::adjustfield);//右對齊
cout.setf(ios_base::fixed, ios_base::floatfield);//使用定點計數法
cout < < "Right Justification:n";
for (n = 1; n <= 41; n += 10) {
cout.width(4);
cout < < n < < "|";
cout.width(12);
cout < < sqrt(double(n)) < < "|n";
}
輸出結果:
Left Justification:
+1 |+1.000e+00 |
+11 |+3.317e+00 |
+21 |+4.583e+00 |
+31 |+5.568e+00 |
+41 |+6.403e+00 |
Internal Justification:
+ 1|+ 1.00|
+ 11|+ 3.32|
+ 21|+ 4.58|
+ 31|+ 5.57|
+ 41|+ 6.40|
Right Justification:
+1| +1.000|
+11| +3.317|
+21| +4.583|
+31| +5.568|
+41| +6.403|
【 注: 對于setf()
的效果可以通過unsetf()
消除,其原型為void unsetf(fmtflags mask);
。其中,mask是位模式。mask中所有的位都設置為1,將使得對應的位被復位。也就是說,setf()
將位設置為1,unsetf()
將位恢復為0。】
6. 標準控制符
對于用戶來說,使用setf()
進行格式化并不是最友好的方法。為此C++提供了多個控制符來完成相應的格式化效果,其能夠調用setf()
,并自動提供正確的參數。例如我們前面介紹過的dec
、hex
和oct
。C++常用控制符如下表所示:
7. 頭文件iomanip
使用iostream
工具來設置一些格式值(如字段寬度)非常麻煩。為了簡化工作,C++在頭文件中提供了其他的一些控制符,不但可以提供前面提到過的格式設置,而且用起來方便。其中常用的控制符如下:
setprecision()//設置精度,其接受一個指定精度的整數參數
setfill() //填充字符,其接受一個指定填充字符的char參數
setw() //設置字段寬度,其接受一個指定字段寬度的整數參數。
由于它們都是控制符,因此可以用cout
語句連接起來。這樣,setw()
控制符在顯示多列值時尤其方便。其使用方法如下例所示:
#include < cmath >
#include < iomanip >
#include < iostream >
int main() {
using namespace std;
// use new standard manipulators
cout < < fixed < < right;
// use iomanip manipulators
cout < < setw(6) < < "N" < < setw(14) < < "square root" < < setw(15)
< < "fourth rootn";
double root;
for (int n = 10; n <= 100; n += 10) {
root = sqrt(double(n));
cout < < setw(6) < < setfill('.') < < n < < setfill(' ') < < setw(12)
< < setprecision(3) < < root < < setw(14) < < setprecision(4) < < sqrt(root)
< < endl;
}
return 0;
}
輸出結果:
N square root fourth root
....10 3.162 1.7783
....20 4.472 2.1147
....30 5.477 2.3403
....40 6.325 2.5149
....50 7.071 2.6591
....60 7.746 2.7832
....70 8.367 2.8925
....80 8.944 2.9907
....90 9.487 3.0801
...100 10.000 3.1623
【 注: 最后一行10.000,是使用fixed控制符導致顯示末尾的0。】
-
控制器
+關注
關注
112文章
16486瀏覽量
179753 -
存儲器
+關注
關注
38文章
7534瀏覽量
164474 -
計數器
+關注
關注
32文章
2276瀏覽量
95092 -
C++語言
+關注
關注
0文章
147瀏覽量
7044
發布評論請先 登錄
相關推薦
STM32CubeIDE是否需要配置任何設置才能正確顯示浮點數呢
浮點數在單片機數據采集監控系統中的應用
浮點數的表示方法
![<b class='flag-5'>浮點數</b>的表示方法](https://file1.elecfans.com//web2/M00/A5/4F/wKgZomUMN9mALScLAAACIFGGUgU666.gif)
STM32如何通過 printf 打印出浮點數
單片機顯示浮點數
![單片機<b class='flag-5'>顯示</b><b class='flag-5'>浮點數</b>](https://file.elecfans.com/web1/M00/D9/4E/pIYBAF_1ac2Ac0EEAABDkS1IP1s689.png)
談一談浮點數的精度問題
![談一談<b class='flag-5'>浮點數</b>的<b class='flag-5'>精度</b>問題](https://file.elecfans.com/web2/M00/5D/CF/poYBAGL0oKOAGnTXAABXAQp6GqM658.png)
評論