输入输出的其他知识¶
控制精度¶
保留两位小数,前面已经讲过,两种写法都可以。
cout 默认通常显示 6 位有效数字,不是小数点后 6 位。数太大或太小时,可能显示成科学计数法。
fixed 配合 setprecision,才是控制小数点后的位数。


控制域宽¶
域宽,就是输出至少占几个字符。默认靠右,不足的部分补空格。
如果数字本身超过 8 个字符,会完整输出,不会截断。
cout 使用 setw,需要头文件 <iomanip>。
int x = 123;
cout << setw(8) << x << setw(8) << x; // 靠右
cout << left << setw(8) << x << setw(8) << x; // 靠左
setw 是 set width 的缩写,只影响紧接着的一次输出,要用几次就写几次。
left 会持续生效,要改回靠右,用 right。


从文件输入输出¶
使用 freopen,需要头文件 <cstdio>,写在 main 里面,读写数据之前。
r 表示读文件,w 表示写文件。输出文件原来有内容,会被覆盖。
后面照常使用 cin、cout,或者 scanf、printf。
输入文件要放在程序的工作目录下。比赛时,文件名、是否使用文件输入输出,都按题目要求来。
freopen 一定要在复赛前练熟,主要是调试要熟练。
输出换行符¶
puts 需要头文件 <cstdio>,输出字符串后会自动换行。
endl 除了换行,还会刷新输出缓冲区。'\n' 只表示换行。
频繁使用 endl 可能拖慢输出,做题时一般用 '\n'。
cin、cout 加速¶
数据量大、输入输出慢时,可以在 main 开头,读写数据之前加上:
第一行,关闭 C++ 流与 C 标准输入输出的同步。
第二行,解除 cin 与 cout 的绑定,读入前不再自动刷新 cout。
开了加速,就统一用 cin、cout,不要再混用 scanf、printf。
是否需要加速,要看数据量和时限,没有超过 1e5 才需要加速的固定界线。
sscanf,从字符串里读数据¶
这部分用到了字符数组,学过字符串后再回来看。
scanf 从标准输入读,sscanf 从字符串里读,用法相似。
需要头文件 <cstdio>。
char s[] = "User M 19 1.85";
char name[10];
char gender;
int age;
double height;
int cnt = sscanf(s, "%9s %c %d %lf", name, &gender, &age, &height);
cnt 是成功读入并赋值的项数,这里是 4。
name 是字符数组,这里不加 &;其他几个变量要加。
%9s 最多读 9 个字符,给数组末尾的 \0 留一个位置。
%c 本身不会跳过空白。
上面格式中,%c 前的空格可以跳过空格、换行等空白字符。
这道题要处理 a.b.c.d:e,sscanf 可以帮忙拆数据。
但读出来,不等于格式合法。还要检查数值范围、前导零、多余字符等,不能只看读出了几个数。
sprintf,把数据写到字符串里¶
这部分也用到了字符数组。
printf 输出到屏幕,sprintf 写到字符数组里,需要头文件 <cstdio>。
char target[100];
char name[] = "Andrea";
char gender = 'F';
int age = 25;
double height = 1.70;
sprintf(target, "%s %c %d %.2lf", name, gender, age, height);
printf("%s", target); // 输出Andrea F 25 1.70
数组要放得下所有内容,还要给末尾的 \0 留一个位置。
sprintf 不会检查数组容量。
stringstream,字符串流¶
需要头文件 <sstream>,使用 string 还需要 <string>。
从字符串里读数据
cin 从标准输入读,ss 从字符串里读,写法一样。
把内容拼成字符串
s 的内容是 "2026-3-20"。
>> 读数据,<< 写数据,str() 取出字符串。
清空后重新使用
这两行作用不同,clear() 不会清空字符串内容。