流和缓冲区
stream:C++程序把输入和输出看做字节流,流充当了程序和流源或流向目标之间的桥梁。
键盘输入每次提供一个字符,因此在这种情况下,程序无需缓冲区来帮助匹配不同的数据传输速率。然而,对键盘输入进行缓冲可以让用户在将输入传输给程序之前返回并更正。C++程序通常在用户按下回车键时刷新输入缓冲区。对于屏幕输出,C++程序通常在用户发送换行符时刷新输出缓冲区。
cin: 对应标准输入流(通常为键盘)
cout:对应标准输出流(通常为显示屏)
cerr:对应标准错误流,用于显示错误消息,这个流没有被缓冲
clog:对应标准错误流
当iostream文件为程序声明一个cout对象时,该对象将包含存储了与输出有关的信息的数据成员,如显示数据时使用的字段宽带、小数位数、显示整数时采用的计数方法以及描述用来处理输出流的缓冲区的streambuf对象的地址。cout<<"Bjarne"通过指向的streambuf对象将字符串"Bjarne"中的字符放到cout管理的缓冲区中。
使用COUT进行输出
1. <<
C++用指向字符串存储位置的指针来表示字符串。对于其他类型的指针,C++将其对应于void*,并打印地址的数值表示。如果要获得字符串的地址,则必须将其强制转换为其他类型。
char name[20] = "Dudly,DDDDDDD";
char* pn = "VVVVVVVVEVEVEV";
cout << "hello!\n";
cout << name<<endl;
cout << pn << endl;
cout << *pn << endl;//pn[0]
cout << (void *)pn << endl;//地址
2.拼接输出
cout<<"a"<<"b"<<"c" ->a + cout<<"b"<<"c"->ab+cout<<"c"->abc //cout连续输出
3.其他ostream方法
put:显示字符
cout.put(65); //显示ASCII为65的A
cout.put(66.3)//显示ASCII为66的B
write:显示字符串 write方法并不会在遇到空字符时自动停止打印字符,而只是打印指定数目的字符,即使超出字符串边界。
#include<iostream>
#include<cstring>
int main() {
using std::cout;
using std::endl;
const char* state1 = "Florida";
const char* state2 = "Kansas";
const char* state3 = "Euphoria";
int len = std::strlen(state1);
cout << "Increasing loop index:\n";
int i;
for (i = 1;i <= len;i++) {
cout.write(state1, i);
cout << endl;
}
cout << "Decreasing Loop index:\n";
for (i = len;i > 0;i--) {
cout.write(state1, i)<<endl;//cout.write()返回cout对象
}
cout << "Exceeding String length:\n";
cout.write(state1, len + 15) << endl;//高能 输出Florida Kansas E
system("pause");
return 0;
}
4.刷新输出缓冲区
控制符flush刷新缓冲区,而控制符endl刷新缓冲区,并插入一个换行符
cout<<"hello baby"<<flush;
cout<<"wait a minite"<<endl;
使用cout进行格式化输出
1.修改显示时使用的计数系统
hex (16进制),oct(八进制),decimal(10进制)
#include<iostream>
int main() {
using namespace std;
cout << "Enter an integer:";
int n;
cin >> n;
cout << "n n*n\n";
cout << n << " " << n*n << "(decimal)\n";
cout << hex;
cout << n << " " << n*n << "(hex)\n";
cout << oct;
cout << n << " " << n*n << "(oct)\n";
cout << dec;
cout << n << " " << n*n << "(decimal)\n";
system("pause");
return 0;
}
2.调整字段宽度
width()方法只影响将显示的下一个项目,然后字段宽度将恢复默认值。默认右对齐。
C++永远不会截短数据,因此如果试图在宽度为2的字段中打印一个7位值,C++将增宽字段,以容纳该数据。
#include<iostream>
int main() {
using namespace std;
int w = cout.width(30);
cout << "default field width = " << w << endl;//cout.width(30)返回的是以前的字段宽度,而不是刚设置的值
cout.width(5);
cout << "N" << ":";
cout.width(8);
cout << "N*N" << ":\n";
for (long i = 1;i <= 100;i *= 10) {
cout.width(5);
cout << i << ':';
cout.width(8);
cout << i*i << ":\n";
}
system("pause");
return 0;
}
3.填充字符
cout.fill() 与字段宽度不同的是,新的填充字符将一直有效,直到更改它为止。
#include<iostream>
using namespace std;
int main() {
cout.fill('*');//填充 一直影响
const char* staff[2] = { "pay","repay" };
long bonus[2] = { 900,1000 };
for (int i = 0;i < 2;i++) {
cout << staff[i] << ":$";
cout.width(7);
cout << bonus[i] << endl;
}
system("pause");
return 0;
}
4.设置浮点数的显示精度
cout.precision(int) 与fill()一样,一直有效。
5.打印末尾的0和小数点
cout.setf(ios_base::showpoint)
6.关于setf()
setf有两个原型。第一个为 fmtflags setf(fmtflags);
fmtflags | 含义 |
ios_base::boolalpha | 输入输出的bool值可以为True和False |
ios_base::showbase | 对于输出,使用C++基数前缀(0,0x) |
ios_base::showpoint | 显示末尾的小数点 |
ios_base::uppercase | 对于16进制输出,使用大写字母,E表示法 |
ios_base::showpos | 在正数前面机上“+” |
注意:fmtflags是bitmask类型,bitmask类型是一种用来存储各个位值的类型。
#include<iostream>
int main() {
using std::cout;
using std::endl;
using std::ios_base;
int temperature = 63;
cout << "Today's water temperatuer:";
cout.setf(ios_base::showpos);//show plus sign
cout << temperature << endl;
cout << "For our programming friends,that's\n";
cout << std::hex << temperature << endl;
cout.setf(ios_base::uppercase);
cout.setf(ios_base::showbase);
cout << temperature << endl;
cout << "about bool:";
cout.setf(ios_base::boolalpha);
cout << true << "\n";
system("pause");
return 0;
}
第二个setf()原型接受两个参数,并返回以前的设置。
fmtflags setf(fmtflags, fmtflags);
第二个参数 | 第一个参数 | 含义 |
ios_base::basefield | ios_base::dec | 十进制 |
ios_base::oct | 八进制 | |
ios_base::hex | 十六进制 | |
ios_base::floatfield | ios_base::fixed | 使用定点计数法 |
ios_base::scientific | 使用科学计数法 | |
ios_base::adjustfield | ios_base::left | 左对齐 |
ios_base::right | 右对齐 | |
ios_base::internal | 符号或基数前缀左对齐, 值右对齐 |
#include<iostream>
#include<cmath>
using namespace std;
int main() {
cout.setf(ios_base::left, ios_base::adjustfield);
cout.setf(ios_base::showpoint);
cout.setf(ios_base::showpos);
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 = 0;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 = 0;n < 41;n += 10) {
cout.width(4);
cout << n << "|";
cout.width(12);
cout << sqrt(double(n)) << "|\n";
}
system("pause");
return 0;
}
调用setf()效果可以通过unsetf()消除
cout.setf(ios_base::boolalpha)
cout.unsetf(ios_base::boolalpha)
cout.unsetf(ios_base::floatfield) //go to default mode
关于定点计数法fixed参考如下:
#include <iostream>
#include <iomanip>
using namespace std;
int main(void)
{
const double value = 12.3456789;
//fixed把精度设置为小数点有效位数
cout << value << endl; // 默认以6精度,所以输出为 12.3457
cout << setprecision(4) << value << endl; // 改成4精度,所以输出为12.35
cout << setprecision(12) << value << endl; // 改成12精度,所以输出为12.345679 不显示末尾0
cout << fixed << setprecision(4) << value << endl; // 加了fixed意味着是固定点方式显示,所以这里的精度指的是小数位,输出为12.3457
cout << value << endl; // fixed和setprecision的作用还在,依然显示12.3457
cout.unsetf(ios::fixed); // 去掉了fixed,所以精度恢复成整个数值的有效位数,显示为12.35
cout << value << endl;
cout.precision(6); // 恢复成原来的样子,输出为12.3457
cout << value << endl;
cout << fixed << setprecision(12) << value << endl; // 改成12精度,所以输出为12.345679 显示末尾0
cout << value << endl;
system("pause");
}
7.标准控制符
cout<<left<<fixed;
可以使用的控制符有:boolalpha(noboolalpha),showbase(noshowbase),showpoint(noshowpoint),showpos(noshowpos),uppercase(nouppercase),
internal,left,right,dec,hex,oct,fixed,scientific.
8.头文件iomanip
setprecision() | 接受一个指定精度的整数参数 |
setfill() | 接受一个指定填充字符的char参数 |
setw() | 接受一个指定字段宽度的整数参数 |
#include<iostream>
#include<iomanip>
#include<cmath>
int main() {
using namespace std;
cout << fixed << right;
cout << setw(6) << "N" << setw(14) << "square root" << setw(15) << "fourth root\n";
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;
}
system("pause");
return 0;
}
欢迎点赞激励我继续学习C++。