cout
cout
用于在屏幕上显示消息,应该是 console output 的简写。它是 C++
中 ostream
对象,该类被封装在 <iostream>
库中,该库定义的名称都放在命名空间 std
中,所以 cout
的全称是 std::cout
。cout
被分类为流对象,这意味着可以使用数据流的。要在屏幕上显示消息,可以发送一串字符到 cout
。例如:
cout << "hello world!" ;
如果要使用 cout
,需要包含库 <iostream>
。
cout 输出的格式控制
在使用 cout
时,可以将一些格式控制操作符放在语句中,来实现不同的输出效果。
以不同进制输出数字
cout
在输出数字时,默认是十进制的方式,还可以使用 hex
、oct
、dec
来控制输出的进制,这三个控制符都包含在 <iostream>
库中。例如:
using namespace std;
auto i = 65534;
cout.setf(ios::uppercase); //输出为大写字母
cout << hex << i << endl; //十六进制输出(默认为小写字母)
cout << oct << i << endl; //八进制输出
cout << dec << i << endl; //十进制输出
cout << setbase(16) << i << endl; //以16进制输出
其中的 setiosflags(ios::uppercase)
表示以大写字母输出(默认是 ios::lowercase
), setbase(n)
方法表示以 n 进制输出,其中的 n 取值为 8、10 或者 16,其余值无输出。这两个函数都包含在库 <iomanip>
中。
使用 setiosflags()
时,可以使用 |
来同时设置多个位,例如:
cout << setiosflags(ios::scientific | ios::showpos) << 12.01 << endl;
控制浮点数的输出
可以通过 setprecision(n)
、setiosflags(ios::fixed)
或 fixed
来对 cout
输出的精度进行控制。这几个控制符都包含在库 <iomanip>
库的 std
命名空间中。
#include <iostream>
#include <climits>
#include <iomanip>
int main(void)
{
using namespace std;
system("chcp 65001");
system("cls");
double p = 1233.141592653;
cout << p << endl;
cout << setprecision(3) << p << endl; //保留两位小数
cout << setprecision(15) << p << endl;
cout << setiosflags(ios::fixed);
cout << p << endl;
cout << fixed << p << endl;
return 0;
}
运行结果如下:
1233.14
1.23e+03
1233.141592653
1233.141592653000089
1233.141592653000089
显示小数点和正负号
此外,还可以使用 setiosflags(ios::showpoint)
来显示小数点,使用 setiosflags(ios::showpos)
来显示正负号。例如:
double i2 = 100;
double d2 = -3.14;
cout << setprecision(4);
cout << setiosflags(ios::showpoint); //显示小数点
cout << i2 << endl;
cout << setiosflags(ios::showpos); //显示正负号
cout << d2 << "\t" << i2 << endl;
输出结果如下:
100.0000
-3.1400 +100.0000
默认显示6个有效位数。
设置宽度和对齐方式
可以通过 setw(n)
函数来设置输出的宽度,当不足宽度的时候,以空格填充剩余的空间,如果超出宽度,则忽略设置的宽度;使用 setiosflags(ios::left|ios::right)
来设置对齐方式。这些都定义在 <iomanip>
库中的 std
命名空间中。例如:
cout.fill(' ');
cout << setw(10) << 100 << setw(10) << 100 << endl;
cout << setiosflags(ios::left) << setw(10) << 100 << setw(10) << 100 << endl;
cout << setiosflags(ios::right) << setw(10) << 100 << setw(10) << 100 << endl;
输出结果为:
100 100
100 100
100 100
输出的结果默认为右对齐。
设置填充字符
在宽度大于字符数量时,cout
默认使用空格填充剩余的空间,可以使用 setfill('*')
来设置为其他的填充字符。例如:
cout << setfill('*') << setiosflags(ios::right) << setw(10) << 100 << setw(10) << 100 << endl;
使用 cout 的成员函数
ostream
类还有一些成员函数,通过 cout
来调用它们也可以控制格式输出。和前面的控制符不同的是,使用成员函数会影响后面所有使用默认格式的输出。如下表:
成员函数 | 控制符 | 说明 |
---|---|---|
precision(n) | setprecision(n) | 设置输出浮点数的精度为n |
width(w) | setw(w) | 指定输出宽度为w个字符 |
fill(c) | setfill(c) | 在指定输出宽度的情况下,多余的空白使用字符c填充 |
setf(flag) | setiosflags(flag) | 将摸个输出格式标志设置为1 |
unset(flag) | resetiosflags(flag) | 将某个输出格式标志设置为0 |
cout.precision(5);
double x = 1123.23456;
cout << x << endl;
cout.width(20);
cout.fill('*');
cout << x << endl;
cin
cin
是 C++中的标准输入流对象,它是 istream
类的对象,包含在 <iostream>
库中, std
命名空间中。cin
主要用于从标准输入读取数据,这里的标准输入,指的是键盘。
当我们从键盘输入字符串的时候,需要按一下回车键才能够将这个字符串送入到缓冲区中。那么键入的回车键也会被转换为一个换行符,这个换行符也会被存储在 cin
的缓冲区并且被当做一个字符来计算。cin
读取数据也是从缓冲区中读取数据,当缓冲区为空时,cin
的成员函数会阻塞等待数据的到来,一旦有数据,就触发函数去读取数据。所以,当缓冲区有残留数据时,cin
的函数会直接取得这些数据而不会请求键盘输入。
cin 常用的读取方法
当使用 cin
从标准输入读取数据时,通常用到的方法有 cin >>
、cin.get()
、cin.getline()
。
cin >>
cin >>
可以连续的从键盘读取数据,以空格、Tab 键或者换行符作为分隔符或者结束符。
当从缓冲区读取数据时,如果第一个字符是空白字符,cin>>
会忽略并将其清除,继续读取下一个字符,如果缓冲区为空,则继续等待。如果读取成功,字符后面的分隔符都是残留在缓冲区内的,cin >>
不做处理。
int a, b, c;
cin >> a >> b >> c;
cout << a << b << c << endl;
上面的代码,将会要求我们输入三个数,并以空白分隔,输出才算完成。cin>>
等价于 cin.operator>>()
,即调用成员函数 operator>>()
进行读取数据。
如果不想略过开头的空白字符,那就使用 noskipws
流控制符。如下:
cin >> noskipws >> a;
cin.get()
这个函数有多个版本的重载。如下:
int cin.get();
istream& cin.get(char& var);
istream& get(char* s, streamsize n);
istream& get(char* s, streamsize n, char delim);
其中的 streamsize
被定义为 long long
类型。
int cin.get() 和 istream& cin.get(char& var)
这两种版本都是一次读取一个字符。
例如下面的代码:
char c1, c2;
c1 = cin.get();
cin.get(c2);
cout << c1 << '\t' << (int)c2 << endl;
运行,输入 a,然后回车,输出如下:
a
a
如上面的代码:
cin.get()
从缓冲区读取单个字符时不忽略空白,直接将其读取,所以变量c2
保存的是一个空行\r
。它的返回值是int
类型,成功则返回读取字符的 ASCII 码值,遇到文件结束符时,返回EOF
,即-1
。在 Windows 中,可以使用 Ctrl+Z 来输入文件结束符。cin.get(char var)
如果成功返回的是cin
对象,所以可以支持链式操作,比如cin.get(a).get(c)
。- 可以使用
cin.get()
来删除缓冲区上一次遗留下来的换行符。
使用 cin.get() 读取一行
cin.get()
的后面两种重载形式,
istream& get(char* s, streamsize n);
istream& get(char* s, streamsize n, char delim);
可以用来读取一行。这两个版本的区别是,前者默认以换行符结束,后者可以指定结束符。参数里的 n
表示目标空间的大小。
例如下面的代码:
#include <iostream>
int main(void)
{
using namespace std;
system("chcp 65001");
system("cls");
char arr1[100] = {NULL};
cin.get(arr1, 100);
char a;
cin.get(a);
cout << arr1 << " " << (int)a << endl;
system("pause");
return 0;
}
运行的结果:
hello world //输入
hello world 10
从上面的代码中,可以看出:
- 读取一行时,遇到换行符时停止读取,但是对换行符不做处理,换行符依然残留在输入缓冲区。
- 第二次使用
cin.get(a)
将换行符读入变量a
,输出的 ASCII 码值为 10 。就是上一次残留的换行符。 - 这种方法读取一行时,只能将字符串读入 C 风格的字符串中,即
char*
,使用 C++ 的getline()
函数可以将字符串读入string
类型。
cin.getline 读取一行
这个函数可以从键盘读取一个字符串,还可以以指定的结束符结束。它不会将换行符残留在缓冲区。函数有两个重载的版本,如下:
istream& getline(char* s, streamsize count); //默认的换行符结束
istream& getline(char* s, streamsize count, char delim); //delim 指定结束符
例如下面的代码:
#include <iostream>
int main(void)
{
using namespace std;
char arr1[100] {0};
cin.getline(arr1, 100);
cout << arr1 << endl;
system("pause");
return 0;
}
cin 的条件状态
使用 cin
读取键盘输入时,一旦出错,cin
将设置条件状态(condition state)。条件状态定义如下:
- goodbit :无错误
- eofbit :已经到达文件尾
- failbit :非致命的输入/输出错误,可挽回
- badbit :致命的输入/输出错误,无法挽回
这些条件状态都有对应的成员函数,可以用来设置、读取当前的条件状态。这些成员函数如下:
函数 | 说明 |
---|---|
cin.eof() | 如果流 cin 的 eofbit 为1,则返回 true |
cin.fail() | 如果流 cin 的 failbit 位为1,则返回 true |
cin.bad() | 如果流 cin 的 badbit 位为1,则返回 true |
cin.good() | 如果流 cin 的 goodbit 位为1,则返回 true |
cin.clear(flags) | 清空状态标志位,将给定的标志位 flags 设置为0,无返回值,如果不带参数,那么则是将清除所有的非good状态 |
cin.setstate(flags) | 将对应的 flags 设置为1,无返回值 |
cin.rdstate() | 返回当前状态。返回值类型为 iostate |
cin.ignore() | 它有两个参数,第一个是整型,第二个是 char 类型。它表示从输入流 cin 中提取第一个参数指定的字符数量,然后将这些字符忽略,如果提取的数量达到指定值或者字符等于第二个参数指定的字符时,该函数将终止。否则,继续等待,直到两个条件之一满足。第二个参数默认值为 EOF |
例如下面的代码:
#include <iostream>
int main(void)
{
using namespace std;
system("chcp 65001");
system("cls");
int a;
while(true)
{
cin >> a;
cout << "位状态:good=" << cin.good() << ", eof=" << cin.eof() << ", bad=" << cin.bad() << ", fail=" << cin.fail() << endl;
//文件尾,可以使用Ctrl+Z
if(cin.eof())
{
cout << "文件尾命令" << endl;
exit(1);
}
if(cin.fail())
{
cout << "输入的非数字。" << endl;
cin.clear();
cin.ignore(1000,'\n'); //忽略后面的所有内容
continue;
}
}
system("pause");
return 0;
}
运行结果:
1
位状态:good=1, eof=0, bad=0, fail=0
a
位状态:good=0, eof=0, bad=0, fail=1
输入的非数字。
^Z
位状态:good=0, eof=1, bad=0, fail=1
文件尾命令
我们可以看到,在输入正确的类型(int)后,good 位标志为1。输入非数字时,fail 位被设置。当使用 clear() 函数进行清除状态后,除 good 位外所有的位都被设置为0。
其他用于读取的函数
这些函数不是 cin
的成员函数,但也可以用于读取输入。
gets() 函数
gets()
函数可以一直读取,直到遇到换行符或者文件尾,它的读取不设上限,所以必须保证缓冲区足够大。它不会让换行符残留在缓冲区。它是 C 语言的库函数。使用如下:
#include <iostream>
int main(void)
{
using namespace std;
char arr1[100] {0};
gets(arr1);
cout << arr1 << endl;
system("pause");
return 0;
}
getchar() 函数
getchar()
读取一个字符并返回,可以读取空白,遇到换行符停止。也会处理结尾的换行符。
#include <iostream>
int main(void)
{
using namespace std;
char c;
c = getchar();
cout << c << endl;
system("pause");
return 0;
}
getline() 函数
getline()
函数读取一整行,它是在 std
命名空间中的全局函数,这个函数的参数使用了 string
类型,所以声明在了 <string>
头文件中。getline()
从标准输入设备中读取一行,当遇到下面三种情况之一会结束读取:
- 文件结束 EOF。
- 遇到行分隔符。
- 输入达到最大的限度。
这个函数有两个重载的版本:
istream& getline(istream& is, string& str); //默认以换行符 \n 分隔行
istream& getline(istream& is, string& str, char delim); //指定分隔符
例如下面的代码:
#include <iostream>
int main(void)
{
using namespace std;
while(true)
{
string str;
getline(cin, str);
cout << str << endl;
}
system("pause");
return 0;
}
getline()
函数遇到结束符时,会将结束符一并读入指定的 string 中,再将结束符替换为空字符。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。