寫C/C++測試題目時如何讀取測資
tags: 部落格文章
以前寫測試題目的時候最麻煩的第一步就是如何讀測資了
方法有很多cin/cout是最簡單的,但是相對的會比較費時,建議是盡量避開全部都使用 printf 和 scanf。
再來第二個問題是,在本地測試的時候會把測資寫到檔案裡面讀取,但是上傳之後是直接從stdin輸入,導致上傳的時候還要修改一下,
這邊也一併提出解決辦法,整理一下我認為最佳的解法。
說明
先說明如何讀取的代碼
char buff[32];
while (scanf("%s", buff)!=EOF) {
printf("%s\n", buff);
}
直接用一個while包起來,代碼從裡面開始寫就可以了。
再來是解決上傳修改代碼的問題使用這個函式,可以直接修改scanf讀取檔案,而不是從stdin讀取,這樣代碼就不用修改了
freopen("input.txt", "r", stdin); // scanf從檔案讀取
freopen("output.txt", "w", stdout); // printf 輸出到檔案
因為函式會略微影響效能,應該有不少人是用define去包起來的
#define ONLINE_JUDGE
#ifndef ONLINE_JUDGE
if(in) freopen("input.txt", "r", stdin);
if(out) freopen("output.txt", "w", stdout);
#endif // ONLINE_JUDGE
如此一來只要註解掉第一行的 define 中間代碼就不會被執行了
不過這邊推薦一個更好的方式,用 inline 函式,效果跟 define 是一樣的
inline void debugMode() {
if(in) freopen("input.txt", "r", stdin);
if(out) freopen("output.txt", "w", stdout);
}
加上 inline 的意思是,如果函式符合一定的規則(簡單說就是足夠簡單),編譯器會自動把函式打掉,直接開到呼叫的地方。就等於沒有呼叫函式的意思了,所以速度會快一點。
如果有其他需要寫到函式建議都要加上 inline ,可以省下一點點時間。
完整的範例
#include <cstdio>
#include <cstdlib>
inline void debugMode(const char* in, const char* out) {
if(in) freopen(in, "r", stdin);
if(out) freopen(out, "w", stdout);
}
int main(int argc,char *argv[]) {
debugMode("in.txt", NULL); // 輸出保持在終端機
for (char buff[32]; scanf("%s", buff)!=EOF; ) {
printf("%s\n", buff);
}
}
參考
- https://sites.google.com/site/9braised/fan-si/c1
- https://discuss.codechef.com/t/ifndef-online_judge/17162
沒有留言:
張貼留言