1. 程式人生 > >freopen()重定向的開啟和關閉

freopen()重定向的開啟和關閉

freopen函式

功能

使用不同的檔案或模式重新開啟流,即重定向。

實現重定向,把預定義的標準流檔案定向到由path指定的檔案中。直觀感覺/實際操作都像是把檔案定向到流,難道是說,對流來說就是重定向,大霧)。

如果指定了新檔名,則該函式首先嚐試關閉已與stream(第三個引數)關聯的任何檔案並取消關聯。然後,無論該流是否成功關閉,freopen都會開啟由filename指定的檔案,並將其與關聯,就像fopen使用指定的模式一樣。(先記住後面有用)

引數

檔名

即要開啟的檔案的名字。

其值應遵循執行環境的檔名規範,並且可以包含路徑(如果系統支援)。

模式

使用上面的模式

說明符,檔案將作為文字檔案開啟。為了開啟一個檔案作為二進位制檔案中,“b”的字元必須被包括在模式串。這個附加的“b”字元可以附加在字串的末尾(從而產生以下複合模式:“rb”,“wb”,“ab”,“r + b”,“w + b”,“a + b“)或插入字母和混合模式的”+“符號之間(”rb +“,”wb +“,”ab +“)。

這裡主要用標準流檔案,標準流檔案具體是指stdin、stdout和stderr。其中stdin是標準輸入流,預設為鍵盤;stdout是標準輸出流,預設為螢幕;stderr是標準錯誤流,一般把螢幕設為預設。通過呼叫freopen,就可以修改標準流檔案的預設值,實現重定向。

 

例項

這個方法的好處十分明顯,freopen之後,就能像平常一樣使用scanf,printf,cin,cout

清單一:C++版

 1 #include<iostream>
 2 using namespace std;
 3 
 4 int main()
 5 {
 6     int a, b;
 7     freopen("in.txt", "r", stdin);
 8     freopen("out.txt", "w", stdout);
 9     while (cin >> a >> b)
10 cout << a + b << endl; 11 fclose(stdin); 12 fclose(stdout); 13 14 return 0; 15 }

清單二:C版

 1 #include<iostream>
 2 using namespace std;
 3 
 4 int main()
 5 {
 6     int a, b;
 7     freopen("in.txt", "r", stdin);
 8     freopen("out.txt", "w", stdout);
 9     while (scanf("%d%d", &a, &b) == 2)
10         printf("%d\n", a + b);
11     fclose(stdin);
12     fclose(stdout);
13 
14     return 0;
15 }

清單三:帶路徑的輸入輸出檔案

我用的VS2017,預設在工程資料夾下,只要路徑寫對,可以在任意資料夾下(本人測試只能放在該工程資料夾下的任意資料夾)

 1 #include<iostream>
 2 using namespace std;
 3 
 4 int main()
 5 {
 6     int a, b;
 7     freopen("in.txt", "r", stdin);
 8     freopen("Debug\\out.txt", "w", stdout);
 9     while (scanf("%d%d", &a, &b) == 2)
10         printf("%d\n", a + b);
11     fclose(stdin);
12     fclose(stdout);
13 
14     return 0;
15 }

清單四:競賽常用版

比如,杭電1000題我完全可以這樣提交:

#include <stdio.h> 
#include <iostream> 

using namespace std;
int main() 
{ 
#ifdef ONLINE_JUDGE
#else
    freopen("in.txt","r",stdin);
#endif
    int a,b;
    while(cin>>a>>b)
        cout<<a+b<<endl;
    return 0;
}

在本地機器除錯時,因為沒有定義過ONLINE_JUDGE,所以會執行freopen("in.txt","r",stdin);方便本機上的除錯,當提交到OJ上後,因為有了ONLINE_JUDGE的定義,所以跳過語句freopen("in.txt","r",stdin); 從 int a,b;處開始執行。

 

freopen的“關閉”

在寫程式碼時常出現這種情況:我們從原有檔案使用freopen匯入資料,但之後關閉檔案再次從鍵盤輸入。我們如果直接fclose(stdin),之後的鍵盤輸入肯定不管用。應如何解決?

顯然,如果在使用完freopen之後,如果還需要使用標準輸入輸出,不能把它們直接fclose。

我們不妨再次重定向,把stdin、stdout重定向到控制檯,就能從鍵盤接受輸入、從螢幕輸出。

 1 #include<iostream>
 2 using namespace std;
 3 
 4 int main()
 5 {
 6     int a, b;
 7     freopen("in.txt", "r", stdin);
 8     freopen("Debug\\out.txt", "w", stdout);
 9     while (scanf("%d%d", &a, &b) == 2)
10         printf("%d\n", a + b);
11     //fclose(stdin);
12     //fclose(stdout);
13     freopen("CON", "r", stdin);
14     freopen("CON", "w", stdout);
15     printf("Hello World\n");
16     scanf("%d%d", &a,&b);
17 
18     return 0;
19 }

需要注意,這裡其實沒有真正關閉,只是再次重定向,回到控制檯。

在windows/DOS,讀檔案後用freopen("CON", "r", stdin),寫檔案後  freopen("CON", "w", stdout)。

在linux中,控制檯裝置是 /dev/console:freopen("/dev/console", "r", stdin)。

 

 

 

參考連結:

1、https://blog.csdn.net/SJF0115/article/details/7695723

2、http://www.cplusplus.com/reference/cstdio/freopen/

3、https://blog.csdn.net/xylon_/article/details/81257268

4、https://zhidao.baidu.com/question/475250525.html

5、http://www.voidcn.com/article/p-ymjofuqn-rs.html