C++ IO首先建立在为Unix环境开发的原始库函数上;ANSI C正式承认这个库时,将其称为标准输入/输出包;
IO相关类定义在头文件iostream和fstream,这些类不是正式语言定义的组成部分,cin,istream都不是关键字。
(1)流简介:
- C++程序将输入和输出看作字符流;对于输入来说,程序从输入流中抽取字符,对于输出来说,程序向输出流中插入字符;
- 输入流可以来自键盘、存储设备或者其他程序;输出流可以输出至显示器、打印机、存储设备或者其他程序。
- 流是程序与流源或流目的之间的中介,这样C++就可以对来源不同的字符做相同处理。
(2)管理输入:
- 两个阶段:将流与程序绑定在一起,将流与源绑定在一起
(3)管理输出:
- 两个阶段:将流与目的绑定在一起,将流与程序绑定在一起
(4)缓冲区简介
1.2 输入输出中比较重要的类缓冲区就是一块存储空间,它是为了匹配程序处理速度和外设处理速度;比如程序一次处理1byte,但是磁盘一次读取512bytes;又或者程序一次处理1byte,可以1byte地从磁盘读取,但是由于硬件读取一次数据复杂且 *** 作慢,因此使用缓冲区可以加快程序处理速度。
flushing the buffer:刷新缓冲区就是清空缓冲区地内容以备下次使用。
- streambuf:提供缓冲区,有成员方法 填满缓冲区、获取缓冲区内容、刷新缓冲区、管理缓冲区
- ios_base:表示流的一般属性 比如文件是否打开、是二进制流还是文本流等等
- ios:基于ios_base,并且它包含了一个指针成员指向一个streambuf对象
- ostream:继承自ios类并提供了输出方法
- istream:继承自ios类并提供了输入方法
- iostream:继承自ostream类和istream类
- ostream.h转换为ostream,将ostream类放置到std命名空间中
- I/O类被重写,开发了I/O类模板包括basic_istream
和basic_ostream 。实现了char,wchar_t具体化;istream和ostream是char的具体化,cout输出字符流,wistream和wstream是wchar_t的具体化,wcout用于输出宽字符流。 - ios基类中的一些独立与类型的信息被移动到ios_base类中,比如格式化常量ios::fixed变为ios_base::fixed,还新增了一些常量
- cin对象:对应标准输入流,默认情况下这个流与标准输入设备匹配(键盘);wcin对象用于wchar_t类型;
- cout对象:对应标准输出流,默认情况下这个流与标准输出设备匹配(显示器),借助streambuf管理流;wcout对象用于wchar_t类型;
- cerr对象:对应于标准错误流(可以用于显示错误信息),默认情况下这个流与标准输出设备匹配(显示器),这个流是不缓冲的;wcerr对象用于wchar_t类型;不受重定向的影响,即使重定向了输入输出流,错误信息还是打印到显示器上
- clog对象:对应于标准错误流,默认情况下这个流与标准输出设备匹配(显示器),这个流是缓冲的;wclog对象用于wchar_t类型。不受重定向的影响,即使重定向了输入输出流,错误信息还是打印到显示器上
修改标准输入和标准输出关联的工具。(比如输出到文件,而不是显示器)
2 cout的使用当创建cout类时会自动打开一个流,创建一个缓冲区,并将流和缓冲区联系起来
C++在输出时将数据看作字符流。
各种char字符可以直接显示,但是对于各种数据包括int,long,float,double就无法直接解析为字符了
C++中将使用cout的<<称为插入操作符,意味着将右侧的信息流传递到左侧(因为<<是左移运算符,相当于给了个方便记忆的解释)
因此cout类重载了<<操作符,重载了适合多种数据类型的<<操作符成员函数,将数据类型转换为文本形式的字符流;以下数据类型皆被重载:unsigned char、signed char、char、short、unsigned short、int、unsigned int、long、unsigned long、long long (C++11)、unsigned long long (C++11)、float、double、long double
重载原型为:ostream & operator<<(type);
ostream为const signed char *、const unsigned char *、const char *、void *重载了<<操作符,因此,可以使用cout<<输出显示字符串;这个方法使用
来判断是否停止显示字符。
如果要显示字符串的地址,由于传递指针输出了整个字符串,因此将其强制转换为void *类型可以显示字符串的地址。举例:
cout << "输出与指针*********************************************************************" << endl;
int eggs = 12;
const char* amount = "dozen";
cout << &eggs; // prints address of eggs variable
cout << amount; // prints the string "dozen"
cout << (void*)amount<<endl; // prints the address of the "dozen" string
运行结果:
输出与指针*********************************************************************
008FFD9Cdozen0041BC80
2.3 输出连接
<<(type);
ostream & operator<<实现输出连接
根据上述函数原型可以知道,返回值是ostream类型的引用,这就可以使得cout<< “We have " << count << " unhatched chickens.\n”;
举例:
cout << "输出连接***********************************************************************" << endl;
cout << "We have " << eggs << " unhatched chickens.\n";
运行结果:
输出连接***********************************************************************
We have 12 unhatched chickens.
2.4 输出字符cout.put()
原型:
template <class type>
//type为char或wchar_t
ostream & put(type);
当传递的实参不是char或wchar_t时,会执行自动转换将其转换为char或wchar_t类型,这个很适合早期发行版本2.0,在那些版本中,使用int值表示字符。
cout << 'W';//在早期发行版本2.0,这个会输出W的ASCII码,当前版本会输出字符W
cout.put('W');//在早期发行版本2.0,这个会输出W字符,当前版本会输出W字符
一些编译器为char, unsigned char, and signed char重载了put(),但是这会给自动转换int实参带来歧义,因为int可以转换为其中任何一个。
举例:
cout << "cout.put()*********************************************************************" << endl;
cout.put('W'); // display the W character
cout.put('I').put('t'); // displaying It with two put() calls
cout.put(65); // display the A character
cout.put(66.3); // display the B character
cout.put(65); // display the A character
cout.put(66.3) << endl; // display the B character
运行结果:
cout.put()*********************************************************************
WItABAB
2.5 输出字符串cout.write()
原型:
basic_ostream<charT,traits>
& write(const char_type* s, streamsize n);
第一个参数提供了需要显示的字符串地址,第二个参数指示了显示几个字符;cout.write()成员函数不会判断字符串是否结尾,指定显示几个字符就显示几个,即使它过界了。返回值为cout,说明支持输出连接
举例:
cout << "cout.write()*******************************************************************" << endl;
const char* state1 = "Florida";
const char* state2 = "Kansas";
const char* state3 = "Euphoria";
int len = std::strlen(state2);
cout << "Increasing loop index:\n";
int i;
for (i = 1; i <= len; i++)
{
cout.write(state2, i);
cout << endl;
}
// concatenate output
cout << "Decreasing loop index:\n";
for (i = len; i >
0; i--)
cout.write(state2, i) << endl;
// exceed string length
cout << "Exceeding string length:\n";
cout.write(state2, len + 5) << endl;
long val = 560031841;
cout.write((char*)&val, sizeof(long))<<endl;
运行结果:
cout.write()*******************************************************************
Increasing loop index:
K
Ka
Kan
Kans
Kansa
Kansas
Decreasing loop index:
Kansas
Kansa
Kans
Kan
Ka
K
Exceeding string length:
KansasEup
aha!
2.6 清空输出缓存
2.7 cout针对不同数据类型的输出格式
2.8 cout以不同进制显示整数
2.9 设置当前字段宽度cout.width()
2.10 更改填充字符cout.fill()
2.11 更改浮点数显示精度cout.precision()
2.12 ios_base成员函数setf()的使用
2.13 标准流 *** 纵符
<<流操纵符;即可设置相应的位置。
2.14 iomanip头文件
欢迎分享,转载请注明来源:内存溢出
缓存一般是512bytes或者其倍数。
在显示器输出时,三种情况可清空缓存
1.发送一个新行给缓冲器,endl
2.当输入挂起时
3.使用工具 flush()函数<
cout << "清空输出缓存*******************************************************************" << endl;
cout << "Enter a number: ";
float num;
cin >>
num;
cout << "Hello, good-looking! " << flush;
cout << "Wait just a moment, please." << endl;
清空输出缓存*******************************************************************
Enter a number: 99
Hello, good-looking! Wait just a moment, please.
(1)char:占用一个字符的位置
(2)整形:占用足够显示它的字符位置数(十位数占用两个字符位置,个位数占用一个字符位置),如果是负数要在前面加一个-号
(3)字符串:占用字符串长度的字符位置数
(4)浮点型:显示的有效位数为6位,尾部的0不显示
cout << "cout针对不同数据类型的输出格式***************************************************" << endl;
cout << "12345678901234567890\n";
char ch = 'K';
int t = 273;
cout << ch << ":\n";
cout << t << ":\n";
cout << -t << ":\n";
double f1 = 1.200;
cout << f1 << ":\n";
cout << (f1 + 1.0 / 9.0) << ":\n";
double f2 = 1.67E2;
cout << f2 << ":\n";
f2 += 1.0 / 9.0;
cout << f2 << ":\n";
cout << (f2 * 1.0e4) << ":\n";
double f3 = 2.3e-4;
cout << f3 << ":\n";
cout << f3 / 10 << ":\n";
cout针对不同数据类型的输出格式***************************************************
12345678901234567890
K:
273:
-273:
1.2:
1.31111:
167:
167.111:
1.67111e+06:
0.00023:
2.3e-05:
ios_base是ios的基类,ios是一个模板类包含了char和wchar_t的专门化,ios_base包含了非模板的特征<<操作符;这几个工具在std命名空间中
流 *** 纵符dec,hex,oct:ios_base中有工具dec,hex,oct使得数据以不同进制显示;dec(),hex(),oct()是函数,并且重载了
注意事项:
1.无法使用二进制显示;
2.在更改进制显示方式之后,系统默认后面使用该方式显示数据,如果有显示为其他进制形式的需要重新设置进制显示方式
三种格式:
hex(cout);<
cout.setf(ios_base::dec);
显示bool类型:
cout << "cout以不同进制显示整数***********************************************************" << endl;
/*cout以不同进制显示整数*/
i = 90;
cout << "以十进制显示i:" << dec << i << endl;//以十进制显示
cout << "以八进制显示i:" << oct << i << endl;//以八进制显示
cout << "以16进制显示i:" << hex << i << endl;//以16进制显示
//如需更改为十进制显示方式,则可以使用以下方式
cout.setf(ios_base::dec);
cout << "以十进制显示i:" << i << endl << endl;
/*bool数据类型显示*/
cout << "bool数据类型显示" << endl;
bool is_true = true;
cout.setf(ios_base::boolalpha);//可以显示为true或false
cout << "is_true = " << is_true << endl;
is_true = false;
cout << "is_true = " << is_true << endl << endl;
cout以不同进制显示整数***********************************************************
以十进制显示i:90
以八进制显示i:132
以16进制显示i:5a
以十进制显示i:90
bool数据类型显示
is_true = true
is_true = false
两种原型:
int width();//返回当前字段宽度
int width(int i);//将字段宽度设置为i,并且返回之前的字符宽度,以备返回上一步的字段宽度。
使用格式:<
注意事项:
1.width()只影响下一次的cout,然后字段宽度将恢复默认值
2.显示为右对齐,多余的字段位置将使用空格填充
cout << "width()***************************************************************************" << endl;
int w = cout.width(30);
cout << "default field width = " << w << ":\n";
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";
}
cout.width(5);
cout << 9.888889999 << endl;//将不会截断
width()***************************************************************************
default field width = 0:
N: N * N:
1: 1:
10: 100:
100: 10000:
9.88889
cout.fill('*');
这对于打印支票很有用,因为这样就不能随意在填充部分随意加数字了。
cout << "更改填充字符****************************************************************************" << endl;
cout.fill('*');
const char* staff[2] = { "Waldo Whipsnade", "Wilmarie Wooper" };
long bonus[2] = { 900, 1350 };
for (int i = 0; i < 2; i++)
{
cout << staff[i] << ": $";
cout.width(7);
cout << bonus[i] << "\n";
}
更改填充字符****************************************************************************
Waldo Whipsnade: $****900
Wilmarie Wooper: $***1350
默认情况下是显示六位有效数字;可以使用precision()设置精度;
cout.precision(2);
注意事项:
1.在设置精度后,后面会一直使用这个精度直到下一次更改精度
cout << "设置小数显示精度:precision()***********************************************************" << endl;
double j = 3333.1415926;
/*设置显示有效数字位数*/
cout << "默认情况显示(6位):" << j << endl;//输出浮点数时,默认情况下保留六位有效数字
cout.precision(9);//可以使用cout.precision(n)设置输出浮点数时保留n位有效数字
cout << "设置有效数字位数为9位时:" << j << endl;
cout.precision(3);//当有效数字位数小于整数有效数字位数时,使用科学计数法显示
cout << "设置有效数字位数为3位时:" << j << endl << endl;
设置小数显示精度:precision()***********************************************************
默认情况显示(6位):3333.14
设置有效数字位数为9位时:3333.14159
设置有效数字位数为3位时:3.33e+03
ios_base类中有一个受保护的数据成员,这个数据成员的各位控制着格式化的各个方面(这些位置1则打开该模式);
ios_base::boolalpha true显示为true,false显示为false ios_base::showbase 输出时使用前缀 OX,ox(进制缩写)等等 ios_base::showpoint 输出小数点和无效0(就尾巴上的0) ios_base::uppercase 输出16进制时使用大写,输出使用科学计数法时使用大写E ios_base::showpos 在正数前面加+号,只适用于十进制,其他进制不用显示+号
fmtflags setf(fmtflags);//输入参数为bitmask类型,指出要设置哪一位;返回值为bitmask类型,指出以前的设置
fmtflags setf(fmtflags , fmtflags );//第一个参数为bitmask类型,指出要设置哪一位;第二个参数为bitmask类型,指出要清除第一个参数中的哪些位;返回值为bitmask类型,指出以前的设置
cout.setf(ios_base::hex, ios_base::basefield);//取消ios_base::basefield原来的设置,将其设置为hex
Second Argument First Argument Meaning 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 符号左对齐,数字右对齐
注意事项:在C++标准中,混合模式和科学计数法模式都有两个特征:
1.精度是指小数点后面的数据位数
2.尾部的0自动显示
ios_base::fmtflags old = cout.setf(ios::left, ios::adjustfield);
cout.setf(old, ios::adjustfield);
取消设置:
方法1:保存旧设置,然后重置设置
void unsetf(fmtflags mask);//mask是一个位,如果setf()将mask位设置为1,则unsetf()将mask位设置为0
cout << "ios_base成员函数setf()的使用***********************************************************"<< endl;
cout << "一个参数的setf():********************************" << endl;
int temperature = 63;
cout << "Today's water temperature: ";
cout.setf(ios_base::showpos); // show plus sign
cout << temperature << endl;
cout << "For our programming friends, that's\n";
cout << std::hex << temperature << endl; // use hex
cout.setf(ios_base::uppercase); // use uppercase in hex
cout.setf(ios_base::showbase); // use 0X prefix for hex
cout << "or\n";
cout << temperature << endl;
cout << "How " << true << "! oops -- How ";
cout.setf(ios_base::boolalpha);
cout << true << "!\n";
cout << "两个参数的setf():*********************************" << endl;
cout << dec;
// use left justification, show the plus sign, show trailing
// zeros, with a precision of 3
cout.fill(' ');
cout.setf(ios_base::left, ios_base::adjustfield);
cout.setf(ios_base::showpos);
cout.setf(ios_base::showpoint);
cout.precision(3);
// use e-notation and save old format setting
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";
}
// change to internal justification
cout.setf(ios_base::internal, ios_base::adjustfield);
// restore default floating-point display style
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";
}
// use right justification, fixed notation
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";
}
cout << "unsetf():*********************************" << endl;
cout << boolalpha;
cout << true << endl;
cout.unsetf(ios_base::boolalpha); // display 1, 0
cout << true << endl;
//将小数显示模式设置为默认状态,默认状态即为混合模式和科学计数法模式都未设置
cout.setf(0, ios_base::floatfield); // go to default mode
ios_base成员函数setf()的使用***********************************************************
一个参数的setf():********************************
Today's water temperature: +63
For our programming friends, that's
3f
or
0X3F
How true! oops -- How true!
两个参数的setf():*********************************
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|
unsetf():*********************************
true
+1
Manipulator Calls boolalpha setf(ios_base::boolalpha) noboolalpha unset(ios_base::noboolalpha) showbase setf(ios_base::showbase) noshowbase unsetf(ios_base::showbase) showpoint setf(ios_base::showpoint) noshowpoint unsetf(ios_base::showpoint) showpos setf(ios_base::showpos) noshowpos unsetf(ios_base::showpos) uppercase setf(ios_base::uppercase) nouppercase unsetf(ios_base::uppercase) internal setf(ios_base::internal,ios_base::adjustfield) left setf(ios_base::left,ios_base::adjustfield) right setf(ios_base::right,ios_base::adjustfield) dec setf(ios_base::dec, ios_base::basefield) hex setf(ios_base::hex, ios_base::basefield) oct setf(ios_base::oct, ios_base::basefield) fixed setf(ios_base::fixed,ios_base::floatfield) scientific setf(ios_base::scientific,ios_base::floatfield)
cout<<otc;
ostream & setprecision(int);//设置精度
ostream & setfill(char);//设置填充符
ostream & setw(int);//设置宽度
//返回值使得可以实现输出连接
cout << "iomanip头文件************************************************************************" << endl;
cout << noshowpos;
// use new standard manipulators
cout << fixed << right;
// use iomanip manipulators
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;
}
iomanip头文件************************************************************************
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
3 完整测试代码
/*
Project name : _1cout_usage
Last modified Date: 2022年3月12日11点52分
Last Version: V1.0
Descriptions: cout的常用用法
*/
#include
root = sqrt(double(n));
cout << setw(6) << setfill('.') << n << setfill(' ')
<< setw(12) << setprecision(3) << root
<< setw(14) << setprecision(4) << sqrt(root)
<< endl;
}
return 0;
}
评论列表(0条)