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时有三个参数,

  1. 指向输出地址的指针
  2. 最大的输入数量
  3. 读取的文件地址

 

经典例题

 
 
 

C++流输入

cin >> / cout <<

cin 和 cout 函数都包含在<iostream>头文件中

getline() 和 stringstream

getline() 函数是包含在<iostream>里的
stringstream 是一种新的数据格式,字符流格式,在<sstream>中定义
两者结合可以解决如输入若干行数据,每行数据分别求和的问题。

  1. 先整体扫入一个整行
    while(getline(cin,line)){		}
    
  2. 定义一个流,将line转成流
    stringstream ss(line);
    
  3. 按正常方式读取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

ProsCons
Method 1简单、好写不能同时读写文件和 std I/O
Method 2繁琐灵活、可反复读写文件

 

参考文献

《算法竞赛入门经典(第二版)》

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值