1. 修改显示时的计数系统ostream类是从ios类派生而来,ios类是从ios_base类派生而来。ios_base类存储了描述格式状态的信息,例如一个类成员中某些位决定使用哪个计数系统(如八/十/十六进制),另外一个成员决定字段的宽度,且ios_base是ostream间接基类,因此ostream也可以修改计数系统和字段宽度。
对于设置显示整数的计数系统整数,我们使用dec、hex和oct控制符来控制整数是以十进制、十六进制还是八进制显示。例如:
int n = 13;hex(cout); //控制符实际上是函数但不是成员函数,因此不必通过对象来调用,也可以使用cout < < hex;cout < < n; //输出dcout < < hex;//等同hex(cout)cout < < n; //输出dcout < < oct;//等同oct(cout),将输出显示设置为八进制cout < < n; // 输出15cout < < dec < < n;//输出132. 调整字段宽度ostream使用width()成员函数将长度不同的数字放到宽度相同的字段中,该方法的原型如下:
int width(); //该方法返回字段宽度的当前设置int width(int i); //该方法将字段宽度设置为i个空格,并返回以前的字段宽度值。这样使得能够保存以前的值,以便以后恢复宽度值使用width()方法只影响将显示的下一个项目,然后字段的宽度将恢复为默认值。例如:
cout < < 字段默认宽度: < < cout.width() < < endl;cout < < 12345 < < endl;//显示12345,方便查看后面每个对象显示的时候占用的宽度cout.width(3);//将字段宽度设置为3cout < < 'a' < < 'b' < < 'c' < < endl;cout.width(2);cout < < aaa;//测试当字节宽度设置过小,是否影响显示,该语句执行后字符宽度将恢复为默认值0auto i = cout.width(3);//i=0auto j = cout.width(4);//由于上一个语句已经将宽度设置为3,因此j=3auto k = cout.width(1);//k=4cout < < endl;cout < < i = < < i < < endl;cout < < j = < < j < < endl;cout < < k = < < k < < endl;其对应的输出为
字段默认宽度:012345 abcaaai = 0j = 3k = 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.1415b = 0.123457a = 3.1b = 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.1415b = 0.123457a = 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); //使用hexcout < < 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 = 0x1cout.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);//显示小数点和末尾的0cout.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 #include #include 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。】
汽车电扇恒温控制开关电路
汽车内部灯延迟电路图讲解
专属综合智能解决方案落地,涂鸦智能助力三魁镇打造数智化城镇样板
Intel DG1独显拆解评测详解
微软Surface官方详细配置曝光
怎么修改显示时的计数系统?怎么设置浮点数的显示精度?
智能儿童手表受市场热捧 繁荣背后有隐忧
立讯收购Qorvo会产生哪些影响?
无处不在的AI,鲲鹏与腾为何能如影随形
物联网平台市场进入了什么阶段
iOS11正式版今晚1点正式推送:新功能颇多,修复旧设备的Bug,你准备升级吗?
基于iOS技术开发的安防移动客户端
日本家用美容仪哪家强?看谁与宙斯雅萌相媲美!
AT32 MCU Printf的功能使用方法
用于紫外线杀菌灯的电子镇流电路分享
施耐德电气智能配电2022,数字引擎助力“双碳”加速度
新加坡杭州科技园电气火灾监控系统的应用的应用
温度传感器有哪些分类分别基于什么原理
参数测量单元(PMU)的布线指南
NE3402E变送器的工作原理及性能特点