cin和cout进阶
本节介绍cin和cout更多的用法,并对比cin,cout和printf,scanf的区别
-
cin,cout是对象,有数据成员和成员函数。比如cin对象还有cin.get()方法
而printf和scanf仅是函数
-
cin和cout输入输出数据的写法比scanf和printf简单一些,但也意味着它不能直接做到对数据的输入输出做到灵活的控制。
比如 pi = 3.1415926,我想要保留2位小数输出pi怎么办?
c语法很容易做到:printf(“%.2d”,pi);而cout似乎对此一筹莫展。
其实iomanip头文件就可以帮我们解决cout控制输出格式的问题
iomanip,io代表输入输出,manip是manipulator(操纵器)的意思
举个栗子
#include<iostream> #include<iomanip> using namespace std; int main() { double PI = 3.141592; cout << PI << endl; // 默认全部输出 3.141592 cout << setprecision(2) << PI << endl; //保留两位有效数字 3.1 cout << fixed << setprecision(2) << PI << endl; //保留两位小数 3.14 return 0; }
单独的setprecision(n) 表示保留n位有效数字,fixed和setprecision(n) 结合使用表示保留n位小数
你还可以设置字段宽度以及使用科学计数法表示
#include<iostream> #include<iomanip> using namespace std; int main() { double PI = 3.141592; cout << setfill('*') << setw(20) << PI << endl; cout << setfill('*') << setw(20) << left << PI << endl; /* 输出: *************3.14159 3.14159************* 说明: setfill(n):设置字符填充,n可以是字符常量或字符变量 setw(n):设置字段宽度为n位 left表示数据左对齐,不加left表示右对齐 */ cout << scientific << PI << endl; cout << scientific << uppercase << PI << endl; /* 输出: 3.141592e+00 3.141592E+00 说明: scientific表示将数据按科学计数法显示 uppercase表示科学计数法表示中E会大写 */ return 0; }
更多有关iomanip的内容,请自行在网上查阅资料
-
输入输出进制转换
cin和cout还可以输入和输出八进制和十六进制数;这时要设置转换基数的操作符dec,hex和oct。其中dec把转换基数设置成十进制,hex把转换基数设置成十六进制,oct把转换基数设置成八进制。
#include<iostream> using namespace std; int main() { int x = 25; cout << hex << x << " " << dec << x << " " << oct << x << endl; // 输出 19 25 31 retrn 0; }
-
cin不能读取空格,换行符
试想一下这个程序:
#include<iostream> using namespace std; int main() { char ch; // ch表示玩家的按键 cin >> ch; // 读取玩家的按键 cout << int(ch); // 打印玩家按键的ASCll码值 return 0; }
你可能希望通过按 空格 来发射子弹,但是运行程序后,无论你怎么按空格和回车(回车键确认输入),程序始终没有输出。这是因为cin忽略了空格和换行符,只有读到其他字符才会让程序继续进行。
不过不用担心,我们可以用 cin.get() 这个函数来解决这个问题。它类似于 getchar();
#include<iostream> using namespace std; int main() { char ch; ch = cin.get(); // 也可以这样使用: cin.get(ch); cout << int(ch); return 0; }
-
cin,cout效率比scanf和printf低
// 验证cout输出比printf慢 #include<iostream> using namespace std; #include<ctime> #include<cstdio> int main() { clock_t start1 = clock(); for (int i = 0; i <= 10000; i++) { cout << i<<'\n'; } clock_t end1 = clock(); clock_t start2 = clock(); for (int i = 0; i <= 10000; i++) { printf("%d\n",i); } clock_t end2 = clock(); cout << "cout use time: " << end1 - start1 << endl; // cout use time: 3463 cout << "printf use time: " << end2 - start2 << endl; // printf use time: 262 // 可见cout输出比printf慢十几倍 return 0; }
scanf比cin快的验证需要些文件操作的知识,我们暂且放过。
不过,cin也是有方法提速的,比如使用魔法代码: std::ios::sync_with_stdio(false);
更详细的内容可以看 探寻C++最快的读取文件的方案
记不住魔法代码完全可以就用scanf和printf来输入输出,当然在输入输出的数据量很大时才考虑这样做。还有一种更快的读取整数的代码(快读算法):只需用getchar即可
int quickRead() { int res = 0, flag = 1; char ch = getchar(); // 跳过非数字字符并判断符号 while (ch < '0' || ch>'9') { if (ch == '-')flag = -1; ch = getchar(); } // 读取所有数字并且合并为一个整数 while (ch >= '0' && ch <= '9') { res = res * 10 + ch - '0'; ch = getchar(); } return res * flag; }
相信你也能写出自己的快写算法,用putchar就行。