这个对经常在OJ上做题的童鞋们很有用。OJ基本都是用标准输入输出(USACO除外)。但如果你在调试的时候也都是从控制台输入,那就太浪费宝贵的时间了。我们可以重定向标准输入,调试的时候从文件读,提交时从标准输入读。

在C语言中,方法比较简单。使用函数freopen(): 



freopen("data.in","r",stdin);  
freopen("data.out","w",stdout);


  

这样就把标准输入重定向到了data.in文件,标准输出重定向到了data.out文件。

这两句代码之后,scanf函数就会从data.in文件里读,而printf函数就会输出到data.out文件里了。

C++中,对流重定向有两个重载函数:



streambuf* rdbuf () const;  
streambuf* rdbuf (streambuf *)


 就相当于get/set方法。

 

代码示例:


1 #include <iostream>
2 #include <string>
3 #include <fstream>
4
5 using namespace std;
6
7 int main(){
8 string str;
9 /*不同的string头文件不一定都支持getline(cin,string);
10 char a[100];
11 cin>>a;
12 cout<<a<<endl;*/
13 streambuf * backup;
14 ifstream fin;
15 ofstream fout;
16 fout.open("data.txt");
17 backup = cout.rdbuf();
18 cout.rdbuf(fout.rdbuf());
19 //cin>>str; /*有空格就会停止*/
20 getline(cin, str); /*直到换行符处才停止*/
21 cout<<str<<endl;
22 cout.rdbuf(backup);
23 fout.close();
24
25 str.clear();
26 fin.open("data.txt");
27 backup = cin.rdbuf();
28 cin.rdbuf(fin.rdbuf());
29
30 cin>>str;
31 cout<<str<<'!'<<endl;
32 cin.rdbuf(backup);
33
34 fin.close();
35 return 0;
36 }




 

注意最后我们使用了cin.rdbuf(backup)把cin又重定向回了控制台

然而,如果用C语言实现同样的功能就不那么优雅了。

因为标准控制台设备文件的名字是与操作系统相关的。

在Dos/Windows中,名字是con

  freopen("con", "r", stdin);

在Linux中,控制台设备是/dev/console

  freopen("/dev/console", "r", stdin);

另外,在类unix系统中,也可以使用dup系统调用来预先复制一份原始的stdin句柄。


------------------越是喧嚣的世界,越需要宁静的思考------------------ 合抱之木,生于毫末;九层之台,起于垒土;千里之行,始于足下。 积土成山,风雨兴焉;积水成渊,蛟龙生焉;积善成德,而神明自得,圣心备焉。故不积跬步,无以至千里;不积小流,无以成江海。骐骥一跃,不能十步;驽马十驾,功在不舍。锲而舍之,朽木不折;锲而不舍,金石可镂。蚓无爪牙之利,筋骨之强,上食埃土,下饮黄泉,用心一也。蟹六跪而二螯,非蛇鳝之穴无可寄托者,用心躁也。