zoukankan      html  css  js  c++  java
  • 《算法竞赛入门经典》学习笔记 2.3 文件操作

    提示2-15:在Windows下,输入完毕后先按Enter键,再按Ctrl+Z键,最后再按Enter键,即可结束输入。在Linux下,输入完毕后按Ctrl+D键即可结束输入。
    使用文件的两种方式包括:freopen和fopen。
    freopen方式
    使用文件最简单的方法是使用输入输出重定向,只需在main函数的入口处加入以下两条语句:

    freopen("input.txt", "r", stdin);
    freopen("output.txt", "w", stdout);

    它使得scanf从文件input.txt读入,printf写入文件output.txt。事实上,不只是scanf和printf,所有读键盘输入、写屏幕输出的函数都将改用文件。尽管这样做很方便,并不是所有算法竞赛都允许你用程序读写文件。甚至有的竞赛允许访问文件,但不允许你用freopen这样的重定向方式读写文件。
    有一种方法可以再本机测试时用文件重定向,但一旦提交到比赛,就自动“删除”重定向语句。代码如下:
    程序2-8 数据统计(重定向版)

    #define LOCAL
    #include <stdio.h>
    #define INF 1000000000
    int main()
    {
        #ifdef LOCAL
            freopen("data.in", "r", stdin);
            freopen("data.out", "w", stdout);
        #endif // LOCAL
        int x, n = 0, min = INF, max = -INF, s = 0;
        while (scanf("%d", &x) != EOF)
        {
            s += x;
            if (x < min) min = x;
            if (x > max) max = x;
            n ++;
        }
        printf("%d %d %.3lf
    ", min, max, (double)s/n);
        return 0;
    }

    重定向的部分被卸载了#ifdef和#endif中。它的含义是:只有定义了LOCAL,才编译两条freopen语句。
    上面的代码在程序首部就定义了LOCAL,因此在本机测试时使用重定向方式读写文件。如果比赛要求读写标准输入输出,只需在提交之前删除#define LOCAL即可。一个更好的方法是在编译选项而不是程序里定义这个LOCAL符号(不知道如何在编译选项里定义符号的读者请参考附录),这样,提交之前不需要修改程序,进一步降低了出错的可能。

    fopen方式
    如果比赛要求用文件输入,但禁止用重定向的方式,可以如下操作:
    程序2-9 数据统计(fopen版)

    #include <stdio.h>
    #define INF 1000000000
    int main()
    {
        FILE *fin, *fout;
        fin = fopen("data.in", "r");
        fout = fopen("data.out", "w");
        int x, n = 0, min = INF, max = -INF, s = 0;
        while (fscanf(fin, "%d", &x) != EOF)
        {
            s += x;
            if (x < min) min = x;
            if (x > max) max = x;
            n ++;
        }
        fprintf(fout, "%d %d %.3lf
    ", min, max, (double)s/n);
        fclose(fin);
        fclose(fout);
        return 0;
    }

    重定向和fopen两种方法各有优劣。重定向的方法写起来简单、自然,但是不能同时读写文件和标准输入输出;fopen的写法稍显繁琐,但是灵活性比较大(例如可以反复打开并读写文件)。顺便说一句,如果想把fopen版的程序改成标准输入输出,只需赋值

    fin=stdin;fout=stdout;

    即可,不要调用fopen和fclose。

  • 相关阅读:
    Ubuntu 16.04安装Guake Terminal终端(使用一键唤醒功能)
    MySQL查询count(*)、count(1)、count(field)的区别收集
    MySQL查询在一个表而不在另一个表中的数据
    Spring MVC中的拦截器/过滤器HandlerInterceptorAdapter的使用
    Spring mvc解析
    RestTemplate的一个请求过程,mark一下
    福袋开发迭代总结
    Rest分享
    写Markdown费事?Typora让你像写word一样行云流水,所见即所得。
    送你几个用起来很爽的Studio插件
  • 原文地址:https://www.cnblogs.com/moonlightpoet/p/5613319.html
Copyright © 2011-2022 走看看