王码编程 OJ
  • 首页
  • 问题列表
  • 比赛
  • 社团
  • 排行榜
  • 记录
  • 新闻通知
  • 课程
    • 入门课程
    • 基础课程
    • 提高课程
  • 帮助
  • 注册
  • 登录

您当前的位置

  • 首页
  • 新闻通知
  • 关于在OJ中使用freopen()函数的问题

关于在OJ中使用freopen()函数的问题

2019年09月09日

发布者:[系统管理员]

文章详情

1718 0

在做题的过程中,我们需要在本地机器上调试。调试过程中,如果输入数据少还可以接受,但如果输入数据很庞大的话,我们就很难忍受一次又一次的重新输入和调试了。为了解决这个问题,我们找到一种简便的方法,那就是freopen函数。

使用freopen函数可以解决测试数据输入问题,避免重复输入,不失为一种简单而有效的解决方法。下面为freopen函数的简介,详细的freopen函数文档可参见:http://www.cplusplus.com/reference/clibrary/cstdio/freopen.html

函数名: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是标准错误流,一般把屏幕设为默认。通过调用freopen,就可以修改标准流文件的默认值,实现输入输出重定向。

例如:freopen("in.txt","r",stdin)的作用就是把标准输入流stdin重定向到in.txt文件中,这样在用scanf或是用cin输入时便不会从标准输入流读取数据,而是从in.txt文件中获取输入。只要把输入数据事先粘贴到in.txt,调试时就方便多了。

类似的,freopen("out.txt","w",stdout)的作用就是把stdout重定向到out.txt文件中,这样输出结果需要打开out.txt文件查看。

 

需要说明的是:

1. 在调用freopen函数实现重定向时,路径名字一定要写正确。

2. 可以不使用输入重定向,仍然通过键盘输入,也可以不使用输出重定向,仍然在控制台查看输出,这都是可以的,看自己需求来定。

3. 这种方法适合在本地机器上调试用,程序调试成功后,提交到oj时不要忘记把与重定向有关的语句删除。
 

对于之前提到的第三点,因为现在不论是NOIP还是NOI都是采用离线判题的方式,因此必须要求选手在比赛时使用freopen函数读取输入数据。考虑到这点,本OJ提供了一种在本地和OJ系统之间无缝切换的方法。

本OJ在判题程序中定义了宏ONLINE_JUDGE,因此提交到本OJ的C/C++代码可以写成这样:

#ifdef ONLINE_JUDGE

   // 在这里写入你要在OJ上完成的代码

#else

   // 在这里写入你要在本地完成的代码

#endif
 

例如:第1000题 A+B Problem完全可以这样提交

#include <cstdio>

#include <iostream>
 

using namespace std;
 

int main()

{

#ifdef ONLINE_JUDGE

   // Do nothing.

#else

   freopen("1000.in","r",stdin);

   freopen("1000.ans", "w", stdout);

#endif

   int a,b;

   while(cin>>a>>b)

       cout<<a+b<<endl;

   return0;

}

在本地机器调试时,因为没有定义过ONLINE_JUDGE,所以会执行freopen("1000.in","r",stdin);和freopen("1000.ans", "w", stdout);方便本机上的调试,当提交到OJ上后,因为有了ONLINE_JUDGE的宏定义,所以跳过这两句的执行,从int a,b;处开始执行。

另外还有两个问题

1. 如何判断文件是否打开了

可以直接使用 if( freopen("a.txt","r",stdin)== NULL ) return false;或if( freopen("b.txt","w",stdout)== NULL ) return false;来表示没有打开

2. 如何使输入输出重新回到我们的控制台里

如果你不想输入或输出到文件了,就加上一句

freopen("CON","r",stdin );对应输入

freopen("CON","w",stdout); 对应输出

其中CON代表控制台

需要注意的问题是,因为参数都是 c_字符串, 故不能把 c++ 里面的 string 类对象作为参数传进去。

比如 string str= "a.txt";

你不能这样写 freopen( str, "r", stdin );

你需要先把 string 类对像化成 c_字符串, 就用 c_str() 函数

上面的可以这样写 freopen( str.c_str(), "r", stdin );

另外请各位教师和各位同学,如果需要提前适应考试环境的话,请在之后提交的程序中加入freopen("题号.in", "r", stdin);表示输入;以及加入freopen("题号.ans", "w", stdout)表示输出。
 

评论:

发表评论

请输入您的评论*

请先登录,才能进行评论

最新发布

通知

题库调整紧急通知!

2025年06月25日

184

通知

题库调整通知

2025年05月12日

249

通知

2023云南省青少年编程

2023年05月30日

3116

新闻

2023云南省青少年编程

2023年05月30日

3613
© 2019 - 2025王码编程  滇ICP备19007937号-1
如果您有任何问题,请联系我们 YNOIer@163.com
您是本系统的第位访问者