【杂谈】用文件输入输出——文件操作入门和宏定义扩展

1.引入

    C++中读写文件的方式有两种:流式和I/O方式。信息学竞赛中一般使用流式文件操作。分为两种:文件指针FILEstream的文件流。

2.输入输出流

    流是磁盘或其他外围设备关联的数据或目的地。通俗来讲,C++程序通过流来与外界交互。在程序开始执行时,stdinstdoutstderr这三个流已经处于打开状态,分别为标准输入标准输出标准错误。前面两个我们已经很熟悉了,可以简单理解成cincout。标准错误,顾名思义,就是发生错误导致stdout不能正常打开时使用它报告错误

3.文件重定向

3.1.语法讲解

    在信息学竞赛中通常只需要同时打开一个输入文件和一个输出文件,因此可以使用freopen函数实现输入输出文件重定向,将stdinstdout等已经打开的文件流重定向到指定文件。需要包含cstdio头文件。

freopen(Filename,mode,stream);

其中,Filename为文件名,应当是一个字符串形式。

mode为打开模式。有两种合法值:

“r”以只读方式打开文本文件,若文件不存在则操作失败
“w”以只写方式打开文件,并删除文件已存在的内容,若文件不存在则创建该文件

当时用只读方式打开文件时,后面的参数应是stdin,否则就是stdout

freopen的具体使用如下:

3.2.例题1——标题统计

题目背景

NOIP2018 普及组 T1

题目描述

凯凯刚写了一篇美妙的作文,请问这篇作文的标题中有多少个字符? 注意:标题中可能包含大、小写英文字母、数字字符、空格和换行符。统计标题字符数时,空格和换行符不计算在内。

输入格式

输入文件只有一行,一个字符串 s s s

输出格式

输出文件只有一行,包含一个整数,即作文标题的字符数(不含空格和换行符)。

输入输出样例

输入 #1
234
输出 #1
3
输入 #2
Ca 45
输出 #2
4

提示

样例 1 说明

标题中共有 3 个字符,这 3 个字符都是数字字符。

样例 2 说明

标题中共有 5 5 5 个字符,包括 1 1 1 个大写英文字母, 1 1 1 个小写英文字母和 2 2 2 个数字字符, 还有 1 1 1 个空格。由于空格不计入结果中,故标题的有效字符数为 4 4 4 个。

数据规模与约定

规定 ∣ s ∣ |s| s 表示字符串 s s s 的长度(即字符串中的字符和空格数)。
对于 40 % 40\% 40% 的数据, 1 ≤ ∣ s ∣ ≤ 5 1 ≤ |s| ≤ 5 1s5,保证输入为数字字符及行末换行符。
对于 80 % 80\% 80% 的数据, 1 ≤ ∣ s ∣ ≤ 5 1 ≤ |s| ≤ 5 1s5,输入只可能包含大、小写英文字母、数字字符及行末换行符。
对于 100 % 100\% 100% 的数据, 1 ≤ ∣ s ∣ ≤ 5 1 ≤ |s| ≤ 5 1s5,输入可能包含大、小写英文字母、数字字符、空格和行末换行符。

3.3.代码示例和具体使用方法

分析题目,很容易就可以写出代码。

#include<iostream>
using namespace std;
int main(){
    int len=0;
    string s;
    while(cin>>s)
         len+=s.length();
    cout<<len<<endl;
    return 0;
}

在竞赛中,我们要把它变成文件输入输出的形式才能正确提交。

#include<iostream>
#include<cstdio>
using namespace std;
int main(){
    freopen("title.in","r",stdin);
    freopen("title.out","w",stdout);
    int len=0;
    string s;
    while(cin>>s)
         len+=s.length();
    cout<<len<<endl;
    return 0;
}

    运行程序,发现一闪而过。别忘了,既然是文件输入输出,那得有文件输入。创建一个文件title.in,将输入样例1复制进去并保存。

在这里插入图片描述
    新建一个title文件夹。将cpp源文件移动到里面,并在里面新建一个txt文件,将其后缀名改为.in。然后复制输入样例1进去并保存。
在这里插入图片描述

    接下来再运行程序,发现还是一闪而过。但不同的是,文件夹里多出了一个title.out文件,打开它,里面就是程序的输出了。
在这里插入图片描述

3.4.宏定义扩展和文件输入输出扩展

    在洛谷等OJ中,程序只能使用流式输入输出,那怎样在本地使用文件输入输出,在OJ测评时使用流式输入输出呢

    最简单粗暴的方式是把freopen注释掉。但在这里要介绍另一种方法。

    大部分OJ在测评时都会定义ONLINE_JUDGE这个宏,只需要判断是否定义了这个宏,就可以判断是否要运行freopen这一段了。以上面的例题为例。

#ifndef ONLINE_JUDGE//从字面意思理解,就是如果没定义一个宏
freopen("输入文件名","r",stdin);
freopen("输出文件名","w",stdout);
#endif//和上面的ifndef相呼应,代表上面那个ifndef能影响到的代码的结尾

ifndef,那是不是有ifdef呢?当然有,其使用方法和ifndef差不多。为了节省时间这里就不再赘述了。

ifdef,也就会有if。和普通的if差不多,宏if的使用示例如下:

#if 1+1==2
    cout<<"1+1=2\n";
#endif

以上这些通过条件来选择是否编译的语句叫做条件编译

undef的作用是取消定义一个宏。比如:

#include<iostream>
using namespace std;
#define MAXN 2020
#undef MAXN
int main(){
    int a[MAXN];
    cout<<MAXN<<endl;
    return 0;
}

    如果运行上面那段的代码,就会报错。这是因为MAXN这个宏已经被释放掉了。不能再使用了。

3.5.小技巧

    如果想进一步节省时间,可以把重定向文件输出的部分注释掉,这样就可以直接在控制台查看输出,非常方便。比如:

#include<iostream>
#include<cstdio>
using namespace std;
int main()
{	
    #ifndef ONLINE_JUDGE
    freopen("title.in","r",stdin);
    //freopen("title.out","w",stdout);
    #endif
    int ans=0;
    string s;
    while(cin>>s)
        ans+=s.length();
    cout<<ans;
	return 0;
}

喜欢就订阅此专辑吧!

【蓝胖子编程教育简介】
蓝胖子编程教育,是一家面向青少年的编程教育平台。平台为全国青少年提供最专业的编程教育服务,包括提供最新最详细的编程相关资讯、最专业的竞赛指导、最合理的课程规划等。本平台利用趣味性和互动性强的教学方式,旨在激发孩子们对编程的兴趣,培养他们的逻辑思维能力和创造力,让孩子们在轻松愉快的氛围中掌握编程知识,为未来科技人才的培养奠定坚实基础。

欢迎扫码关注蓝胖子编程教育
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

蓝胖子教编程

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值