算法竞赛之【输入输出重定向】

当咱们求解acm题目时,一般在设计好算法和程序后,要在调试环境(例如VC等)中运行程序,输入测试数据,当能获得正确运行结果后,才将程序提交到oj中。但因为调试每每不能一次成功,每次运行时,都要从新输入一遍测试数据,对于有大量输入数据的题目,输入数据须要花费大量时间。 ios

一个好的方法是用文件一一把输入数据保存在 文件中,输出数据也保存在文件中。这样,只要事先把输入数据保存在文件中,就没必要每次从新输入了;数据输出在文件中也避免了“输出太多,一卷屏前面的就看不见了”这样的尴尬,运行结束后,慢慢浏览输出文件便可。若是有标准答案文件,还能够进行文件比较”,而无须编程人员逐个检查输出是否正确。事实上,几乎全部算法竞赛的输入数据和标准答案都是保存在文件中的。使用文件最简单的方法是使用输入输出重定向,只需在main函数的入口处加入如下两条语句:算法

freopen("input.txt","r", stdin) ;编程

freopen("output.txt","w", stdout) ;函数

函数名:freopen
声明:FILE *freopen( const char *path, const char *mode, FILE *stream );
所在文件: stdio.h
参数说明:
path: 文件名,用于存储输入输出的自定义文件名。
mode: 文件打开的模式。和fopen中的模式(如r-只读, w-写)相同。
stream: 一个文件,一般使用标准流文件。
返回值:成功,则返回一个path所指定文件的指针;失败,返回NULL。(通常能够不使用它的返回值)
功能:实现重定向,把预约义的标准流文件定向到由path指定的文件中。标准流文件具体是指stdin、stdout和stderr。其中stdin是标准输入流,默认为键盘;stdout是标准输出流,默认为屏幕;stderr是标准错误流,通常把屏幕设为默认。测试

 

上述语句将使得scanf从文件input.txt 读入,printf 写入文件output.txt。事实上,不仅是scanf和printf,全部读键盘输入、写屏幕输出的函数都将改用文件。尽管这样作很方便,并非全部算法竞赛都容许用程序读写文件。甚至有的竞赛容许访问文件,但不容许用freopen这样的重定向方式读写文件。参赛以前请仔细阅读文件读写的相关规定。spa

 

下面以在VC下调试“计算a+b”的程序举例。
【C语法】debug

 1 #include <stdio.h> 
 2 int main()  3 {  4 int a,b;  5 freopen("debug\\in.txt","r",stdin); //输入重定向,输入数据将从in.txt文件中读取 
 6 freopen("debug\\out.txt","w",stdout); //输出重定向,输出数据将保存在out.txt文件中 
 7 while(scanf("%d %d",&a,&b)!=EOF)  8 printf("%d\n",a+b);  9 fclose(stdin);//关闭文件 
10 fclose(stdout);//关闭文件 
11 return 0; 12 } 

【C++语法】设计

 1  2 #include <stdio.h> 
 2  3 #include <iostream.h> 
 3  4 int main()  4  5 {  5  6 int a,b;  6  7 freopen("debug\\in.txt","r",stdin); //输入重定向,输入数据将从in.txt文件中读取 
 7  8 freopen("debug\\out.txt","w",stdout); //输出重定向,输出数据将保存在out.txt文件中 
 8  9 while(cin>>a>>b)  9 10 cout<<a+b<<endl; // 注意使用endl 
10 11 fclose(stdin);//关闭文件 
11 12 fclose(stdout);//关闭文件 
12 13 return 0; 13 14 } 

freopen("debug\\in.txt","r",stdin)的做用就是把标准输入流stdin重定向到debug\\in.txt文件中,这样在用scanf或是用cin输入时便不会从标准输入流读取数据,而是从in.txt文件中获取输入。只要把输入数据事先粘贴到in.txt,调试时就方便多了。 
相似的,freopen("debug\\out.txt","w",stdout)的做用就是把stdout重定向到debug\\out.txt文件中,这样输出结果须要打开out.txt文件查看。
指针

 

提示调试

请在比赛以前了解文件读写的相关规定:是标准输入输出(也称标II/O,即直接读键盘、写屏幕), 仍是文件输入输出?若是是文件输入输出,是否禁止用重定向方式的问文件?

须要说明的是:
1. 在freopen("debug\\in.txt","r",stdin)中,将输入文件in.txt放在文件夹debug中,文件夹debug是在VC中创建工程文件时自动生成的调试文件夹。若是改为freopen("in.txt","r",stdin),则in.txt文件将放在所创建的工程文件夹下。in.txt文件也能够放在其余的文件夹下,所在路径写正确便可。
2. 能够不使用输出重定向,仍然在控制台查看输出。
3. 程序调试成功后,提交到oj时不要忘记把与重定向有关的语句删除。

 

若是比赛中要求用文件输入输出,但禁止用重定向的方式,又当如何呢?

在算法竞赛中,若是不容许使用重定向方式读写数据,应使用fopen和fscant,fprintf进行输入输出。

咱们仍是之前面的例子为例:

【C语法】

 1 #include <stdio.h> 
 2 int main()  3 {  4     int a,b;  5     FILE *fin, *fout;  6     fin = fopen("debug\\in.txt","rb");//debug\\in.txt 你的测试文件的实际路径
 7     fout = fopen("debug\\out.txt","wb");//  8     while(fscanf(fin,"%d%d",&a,&b) == 2)  9         fprintf(fout,"%d \n",a+b); 10     fclose(stdin);//关闭文件 
11     fclose(stdout);//关闭文件 
12     return 0; 13 } 

【C++语法】

 1 #include <iostream>
 2 #include <fstream>
 3 using namespace std;  4 int main()  5 {  6     fstream fin,fout;//定义一个文件输入输出流对象
 7     int a,b;  8     fin.open("debug\\in.txt",ios::in);//debug\\in.txt 你的测试文件的实际路径
 9     fout.open("debug\\out.txt",ios::out); 10     while(!fin.eof()) 11  { 12         
13         fin>>a>>b; 14         if(fin.eof() == true)//若是文件到达末尾退出 eof()是文件流中的错误处理函数,它遇到文件结尾会返回true(一个非零值)。
15             break; 16         fout<<a+b<<endl; 17  } 18     
19     fin.close();//关闭文件 
20     fout.close();//关闭文件 
21     return 0; 22 } 

 

重定向和fopen两种方法各有优劣。重定向的方法写起来简单、天然,可是不能同时读写文件和标准输入输出; fopen 的写法稍显繁琐,可是灵活性比较大(例如,能够反复打开开读写文件)。

【提示】

 若是想把fopen版的程序改为读写标准输入输出,只需赋值"fin = stdin; fout = stdout;" 便可,不要调用fopen和fclose。

相关文章
相关标签/搜索