C++ Basic STD I/O and File I/O
考试须知
- 在比赛前阅读相关规定:确定输入方式为标准I/O或文件输入输出;
- 文件输入输出是否允许重定向。
- 注意 input/output 文件名。
iostream vs stdio
stdio 是C标准库里面的函数库; 对应是C语言常用库的标准输入输出定义
iostream 是C++标准库的头定义; 对应的是C++的输入输出相关库定义
Mac Terminal 输入
ctrl + z 挂起正在运行的进程
ctrl + d 发送EOF
ctrl + c 结束进程
注意在terminal测试的时候使用ctrl + d 做输入结尾
如果使用重定项,在测试输入文件的末尾加上 \n
尽管使用重定向,在terminal输入时仍需输入std input 指令 "./a.out"
scanf/printf ()
scanf("%lld") 的限制
scanf/printf (“%lld”)不保险,在一些 Windows处理时会出现异常;
可以考虑用int导入,再赋值给long long。
scanf("%*s") / printf("%*s")
scanf("%*s")
在 scanf 里的意思,表示忽略要读的项。比如 %*d 就是读一个 %d 该读的东西,但不赋值给任何变量。
scanf("%*d %*d %d", &n);
如果输入 2004 2005 2006
那么 n = 2006
此处转载自@小标 发布于职坐标,侵删。
printf("%*s")
举例说明:
printf("%*s\n",(N-n),"") //输出(N-n)个空格
这里"*"被N-n代替,用于控制最小字符宽度,可以理解为生成N-n个占位符。
注意N-n >= 0
不是所有字符都能如此处理:
printf("%*s\n",(N-n),"#") //输出为(N-n-1)个空格和一个#
连续输入相同字符可以参考我的另一篇文章《C++ Basic String / Char》
处理未知数量的输入
scanf 有返回值,返回值为每一次scanf operation处理的参数数量;
当未知输入数时,可用下述语句:
while(scanf(“%d”, &n) == 1){
...
}
当输入值以 0 结尾时,上述语句可以进阶为:
while(scanf(“%d”, &n) == 1 && n){ //注意:条件语句会先执行scanf
...
}
这个函数有一个明显的限制,当scanf("%c")时,它会读取换行符造成问题,当scanf("%d")时又没法判断一行的结束。
getchar() & fgets(char[] a,maxn,stdin)
getchar()
getchar() 从 stdin 读取一个字符自动忽略空格和TAB,但会读取换行符
可以解决如输入若干行数据,每行数据分别求和的问题。
fgets(char[] a,maxn,stdin)
char[ ] a 一般不在函数体里定义,使用 fgets时有三个参数,
- 指向输出地址的指针
- 最大的输入数量
- 读取的文件地址
经典例题
C++流输入
cin >> / cout <<
cin 和 cout 函数都包含在<iostream>头文件中
getline() 和 stringstream
getline() 函数是包含在<iostream>里的
stringstream 是一种新的数据格式,字符流格式,在<sstream>中定义
两者结合可以解决如输入若干行数据,每行数据分别求和的问题。
- 先整体扫入一个整行
while(getline(cin,line)){ }
- 定义一个流,将line转成流
stringstream ss(line);
- 按正常方式读取ss流
while(ss>>x){ }
Read File
Method 0 for File Read
用文件输入输出(比赛一般会是这种形式,且测试时不用重复输入测试值)
int main(){
freopen(“input.txt”, ”r”, stdin);
freopen(“output.txt”, ”w”, stdout);
//各位看官注意了,博主曾花了1h debug
//原因时在stdin上加了"" 这时会返回no matching function for call to 'freopen'
…
}
Method 1 for File Read
可以考虑使用下列方式进行测试,以避免忘记移除路径:
#define LOCAL
#include<stdio.h>
using namespace std;
int main(){
#ifdef LOCAL
// will only be executed when LOCAL is defined in the header
freopen(“input.txt”, ”r”, stdin);
freopen(“output.txt”, ”w”, stdout);
// 注意使用完整路径时不要加 "/User/用户名",这一部分 terminal 默认会加。
#endif
...
/*
注释掉测试时的中间输出,方便重新debug
*/
}
进阶:可以在IDE编译选项中定义LOCAL,使提交前不用修改程序
Method 2 for File Read
适用于比赛不允许重定向。
#include<stdio.h>
using namespace std;
int main(){
FILE *fin, *fout;
fin = fopen("data.in","rb");
//fin = stdin; //调整输入为std
fout = fopen("data.out","wb");
//fout = stdout; //调整输出为std
...
// will need to subsitude scanf with
fscanf(fin,"%d",&n);
// will need to subsitude printf with
fprintf(fout,"%d",&n);
...
fclose(fin);
fclose(fout);
return 0;
}
Pros and Cons of Method 1 & Method 2
Pros | Cons | |
---|---|---|
Method 1 | 简单、好写 | 不能同时读写文件和 std I/O |
Method 2 | 繁琐 | 灵活、可反复读写文件 |
参考文献
《算法竞赛入门经典(第二版)》