0%

【C/C++】输入与输出(Cin & Cout)

为成为国际语言,C++必须能处理需要16位的国际字符集Unicode,于是在传统的8位char型的基础上添加了wchar_t字符类型。在程序包含iostream文件时,将自动创建8个流对象:cin、cout、cerr、clog以及相对应的用于宽字符流的:wcin、wcout、wcerr、wclog。

Cin

可以将hex oct dec与cin连用,用于指定将输入的整数的进制

1
2
3
int a;
cin>>hex>>a;//输入12h
cout<<a<<endl;//输出18d

当把输入传给字符数组时,会自动在后面加上一个空值字符,使之成为一个字符串。

1
2
3
char name[10];
cin>>name;//当输入>=10时,会出错,因为会自动加'\0'
cout<<name<<endl;

cin检查输入

1
2
3
4
5
6
7
int a;
cin>>a;
cout<<a<<endl;

char name[10];
cin>>name;
cout<<name<<endl;

当输入123sdf或者123 sdf时,结果是a=123 name=sdf

流状态:

​ 由3个ios_base元素组成:eofibtbadbit failbit。

​ 当cin到达文件末尾是,它将设置eofbit

​ 当cin未能读取预期的字符时(如类型不对),它将设置failbit

​ 当cin试图读取不可访问的文件时,可能设置failbit

​ 当有无法诊断的错误时,设置badbit

​ 当全部3个状态都设置为0时,说明一切正常

设置状态

clear:

1
2
3
clear();//将使用默认参数0,这将清楚全部3个状态位:eofibt badbit failbit

clear(eofbit);//将状态设置为eofbit,另外两个状态被清除

而setstate()只影响参数对应的位

1
setstate(eofbit);//将设置eofbit,不会影响其它位

get与getline

​ get(char&)与get(void)不跳过空白的单字符

​ get(char,int,char)与getline(char,int,char)默认情况下是读取整行而不是一个单词。

​ get(void)返回的是int型,因为它可能返回EOF=-1,则下面是错误的

​ cin.get().get()

到底采用哪一种输入方式?

  • 如果希望跳过空白,则使用cin>>ch
  • 如果希望程序检查每一个字符,则用cin.get(ch)

get()与getline()的主要区别在于:get()将换行符或则者分界符留在输入流中,这样接下来的输入操作首先看到的将是换行符或者是分界符,而getline()抽取并丢弃输入流中的换行符

ignore(int n,char)将读取并丢弃接下来的n个字符或直到到达第一个char。

1
2
3
4
5
6
7
int a;

cin.ignore(5,'3');

cin>>a;//输入1312

cout<<a<<endl;//输出12

cin.read()与cin.get()不同的是,read()不会在输入之后加’\0’,因此不能将输入转为字符串

cin.peek()用于返回下一个输入的字符,但是并不把这个字符从缓存中读取出来。

Cin.putback()用于将一个字符插入到输入字符串中,即下一个要读取的字符就是你插入的字符。


Cout

  • 可以直接输出数组名和字符指针以及字符常量。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include<iostream>
using namespace std;

void main()
{
char name[10]="tengwei";
char *p="xidian university";
cout<<"hello world!\n";
cout<<name<<endl;
cout<<p<<endl;//这里显示的是字符串而不是p的值(即不是字符串的地址)

cout<<&name<<endl;//数组的首地址
cout<<&p<<endl;//指针p的地址
cout<<(void*)p<<endl;//这才是字符串的地址!需进行强制转化
//对于其它指针类型,cout认为是void*
}

注意如何输出字符串地址!

  • Ostream定义了put()和write()方法,分别用于字符的显示与字符串的显示

    cout.put()是用来输出单个字符的 比如cout.put(‘\n’); cout.put(‘a’);
    cout.write(s,num);是用来输出字符串的。s是字符串的地址,num是想要输出的字符串的长度,空格也算就算是空字符也算在内。

    例如:cout.write(“tengweitw”,4);将输出teng

  • Write()方法也可用于数值数据:

    1
    2
    3
    longval=560031841;

    cout.write((char*)&val,sizeof(int));//结果为aha!

    Val被显示为4个字符的组合,由于val的十六进制为21616861,而61h变为十进制正好是97即a,68h=104d=h,21h=33=!

Cout进行输出时,并不会立刻发送到目的地,而是先存储在缓存区,直到缓存区填满,然后程序刷新缓存区,把内容发出去,并清空缓存区。这样做可以节省大量时间,毕竟不希望每次有数据就立即发送,因为这样要存取硬盘很多次,浪费时间。我们可以调用flush来刷新,如下面都可以:

1
2
3
4
5
cout<<"hello"<<flush;

flush(cout);

cout.flush();
  • 进制间转换

    十进制:dec

    八进制: oct

    十六进制: hex

    Dec oct hex 这些控制符不是成员函数。它们的作用是长期的,直达重新设置为止。

调整字段宽度:

1
2
3
Int width();//返回当前设置

Int width(int i);//设置宽度为i

注意width只影响接下来的一个项目而已,然后恢复默认值

填充字符:

1
Cout.Fill(‘*’);// 它们的作用是长期的,直达重新设置为止。

精度设置

在默认情况下,精度为显示的总位数,在定点模式和科学模式下,精度指的是小数点后面的位数,默认精度为6(末尾0不显示)

1
Cout.precision(2); // 它们的作用是长期的,直达重新设置为止。

打印末尾的0和小数点

1
cout.setf(ios_base::showpoint);
  • Setf()的用法
    setf()用于控制小数点被显示是的其它几个格式选项。

    Setf()有两个函数原型:

    fmtflags setf (fmtflags fmtfl, fmtflags mask);``fmtflags setf (fmtflags fmtfl);

    其中fmtfl和mask的可选值如下:

fmtfl format flag value mask field bitmask
left, right or internal adjustfield
dec, oct or hex basefield
scientific or fixed floatfield

具体可以查看此链接:http://www.cplusplus.com/reference/ios/ios_base/setf/

具体调用如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
#include<iostream>

using namespace std;

void main()
{

cout<<true<<endl;//1
cout.setf(ios_base::boolalpha);//输入输出bool值,可以为true或false
cout<<true<<endl;//true

cout.setf(ios_base::showbase);//对于输出,使用C++基数前缀
cout<<hex<<63<<endl;//0x3f

cout.setf(ios_base::showpoint);//显示末尾的小数点
cout<<dec<<6.3<<endl;//6.30000

cout.setf(ios_base::uppercase);//对于进制输出,使用大写字母,E表示法
cout<<hex<<63<<endl;//0X3F是大写

cout.setf(ios_base::showpos);//在整数前面加上+
cout<<dec<<63<<endl;//+63

/*下面为有两个参数的输入*/
cout.unsetf(ios_base::basefield);
cout.unsetf(ios_base::adjustfield);
cout.unsetf(ios_base::floatfield);

cout.setf(ios_base::dec,ios_base::basefield);//使用基数,若输入是小数则无效
cout<<12.34<<endl;//12.34,输入是小数则无效
cout.setf(ios_base::oct,ios_base::basefield);//使用基数,若输入是小数则无效
cout<<12<<endl;
cout.setf(ios_base::hex,ios_base::basefield);//使用基数,若输入是小数则无效
cout<<12<<endl;

cout.setf(ios_base::fixed,ios_base::floatfield);//使用定点计数法
cout<<12.34<<endl;
cout.setf(ios_base::scientific,ios_base::floatfield);//使用科学计数法
cout<<12.34<<endl;

cout.unsetf(ios_base::basefield);//消除指定域的设置,恢复默认状态
cout.unsetf(ios_base::adjustfield);//消除指定域的设置,恢复默认状态
cout.unsetf(ios_base::floatfield);//消除指定域的设置,恢复默认状态
cout.unsetf(ios_base::showpoint);//showpoint等个不在上面个域内,应该单独消除

cout.setf(ios_base::left,ios_base::adjustfield);//左对齐
cout.setf(ios_base::right,ios_base::adjustfield);//右对齐
cout.setf(ios_base::internal,ios_base::adjustfield);//符号或基数前缀左对齐,值右对齐

}

上面所用的一些函数都可以用下面的标准控制符来调用:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
#include<iostream>

using namespace std;

void main()//与上面的相对应,就不写注释了
{
cout<<boolalpha<<true<<endl;
// cout<<noboolapha<<true<<endl;//在我的电脑上noboolapha不支持

cout<<showbase<<hex<<63<<endl;
cout<<noshowbase<<hex<<63<<endl;

cout<<showpoint<<12.34<<endl;
cout<<noshowpoint<<12.34<<endl;

cout<<showpos<<12.34<<endl;
cout<<noshowpos<<12.34<<endl;

cout<<uppercase<<hex<<63<<endl;
cout<<nouppercase<<hex<<63<<endl;

cout<<internal<<63<<endl;
cout<<left<<63<<endl;
cout<<right<<63<<endl;
cout<<dec<<63<<endl;
cout<<hex<<63<<endl;
cout<<oct<<63<<endl;
cout<<fixed<<12.34<<endl;
cout<<scientific<<12.34<<endl;

}

图1

坚持原创技术分享,您的支持将鼓励我继续创作!