C/C++ 文件读写
•前言
第一次接触文件读写是在大一的C语言教材中,当时哼哧吧唧的学的贼费劲,虽然最后也学会了,但好像没怎么用过。
在后来,就是在OJ上刷题的时候,编写的代码有时候连样例都不能通过;
这个时候就需要各种修改,然后各种输入样例,调试起来显得很费力,差不多这个时候,才正式开始使用文件读写。
体验真的棒~~
•C中的文件读写-freopen
函数简介
freopen 是被包含于 C标准库头文件 stdio.h 中的一个函数,用于重定向输入输出流。
该函数可以在不改变代码原貌的情况下改变输入输出环境,但使用时应当保证流是可靠的。
函数声明
*FILE freopen(const char* _FileName, const char* _Mode, FILE* _Stream );
- _FileName:需要重定向的文件名或文件路径
- _Mode:代表文件访问权限的字符串
- "r" 表示 只读访问
- "w" 表示 只写访问
- "a" 表示 追加写入
- _Stream:需要被重定向的文件流
- stdin:表示输入重定向(从指定文件中读取数据到程序中)
- stdout:表示输出重定向(将程序中输出的数据输入到指定文件中)
- 返回值:如果成功,则返回指向该输出流的文件指针,否则返回为NULL
测试输出重定向(写文件)
新建一个项目,并命名为文件读写;
在该项目中创建一个 C中的文件读写.c 文件,并添加如下代码:
#include<stdio.h>
#define FILENAME "FILEC.txt"//文件名 void write()
{
freopen(FILENAME, "w", stdout); printf("测试向FILEC.txt中写文件\n");
}
int main()
{
write(); return 0;
}运行该代码,你会发现,在项目文件读写的文件夹下多出一个 FILEC.txt 的文件,打开该文件,你会惊奇的发现,该文件的内容就是你在程序中通过 printf 输出的语句。
通过代码可以看出,freopen 函数只出现在了 write() 函数中,那么如果在主函数中输出 "Hello World",会输出到哪里呢?
让我们通过代码来测试一下。
void write()
{
freopen(FILENAME, "w", stdout); printf("测试向FILEC.txt中写文件\n");
}
int main()
{
printf("TEST1 : Hello World\n");
write();
printf("TEST2 : Hello World\n"); return 0;
}运行该代码,你会发现,在控制台只输出了 "TEST1 : Hello World":
少的那一句呢?
莫非是输出到 FILEC.txt 中了,让我们一探究竟。
果然在这里,通过这个测试,就能发现,在语句 freopen(FILENAME, "w", stdout); 调用后,所有的输出语句都写到了 FILEC.txt 中。
C 语言中提供了文件读写的关闭语句 fclose(stdout) ,那可不可以通过该语句实现随开随关呢?
让我们尝试在 write() 中使用该语句。
void write()
{
freopen(FILENAME, "w", stdout); printf("测试向FILEC.txt中写文件\n"); fclose(stdout);
}
int main()
{
printf("TEST1 : Hello World\n");
write();
printf("TEST2 : Hello World\n"); return 0;
}让我们来运行一下修改后的程序。
运行结果
在 VS2022 上,直接报错了:
而在 CodeBlocks 中测试,成功运行了:
但是, FILEC.txt 文件中却丢失了 printf("TEST2 : Hello World\n"); 语句的输出结果:
所以,通过测试可知,并不能通过 fclose(stdout); 语句实现随开随关 ,正确的写法应该是:
#include<stdio.h>
#define FILENAME "FILEC.txt"//文件名 void write()
{
freopen(FILENAME, "w", stdout); printf("测试向FILEC.txt中写文件\n");
}
int main()
{
printf("TEST1 : Hello World\n"); write(); printf("TEST2 : Hello World\n"); fclose(stdout);//放置到程序结尾处
return 0;
}测试输入重定向(读文件)
在程序所在目录下新建一个 Input.txt 文件,并输入如下信息:
运行如下代码:
#include<stdio.h>
#define FILENAME "Input.txt" int main()
{
freopen(FILENAME,"r",stdin);//读文件 char s[100];
while (scanf("%s", s) != EOF)
puts(s); return 0;
}运行该程序,你会发现,并不需要输入任何数据:
控制台输出的内容刚好是 Input.txt 中的内容。
- scanf("%s", s) != EOF 表示的是读取到文件结尾
- FILENAME 也可以换成 Input.txt 的具体路径
E:\\Documents\\Visual Studio for C++\\文件读写\\文件读写\\Input.txt
- 其中,路径中的 "\\" 可以换成 '/',但不能是 '\'
同理,我们也可以用 fclose(stdin); 来关闭该输入流,但同输出流一样,应该放到程序结尾出:
#include<stdio.h>
#define FILENAME "Input.txt" int main()
{
freopen(FILENAME,"r",stdin);//读文件 char s[100];
while (scanf("%s", s) != EOF)
puts(s); fclose(stdin);//放到程序结尾处
return 0;
}
•C++中的文件读写-fstream
函数简介
C++中对文件操作需要包含头文件 <fstream> (file stream,文件流)。
- ofstream:写操作(output file stream)
- ifstream: 读操作(input file stream)
- fstream : 读写操作(file stream)
写文件
步骤
- 创建流对象:ofstream ofs;
- 打开文件:ofs.open("文件名/文件路径",打开方式);
- 写数据:ofs << "写入的数据"; (将 cout 改为 ofs)
- 关闭文件:ofs.close();
文件打开方式
- ios::out :为写文件而打开文件
- ios::app :追加方式写文件
在代码所在的文件夹下新建一个 FILEC++.txt 文件,添加如下数据:
并运行如下代码:
#include<iostream>
#include<fstream>//包含头文件
using namespace std;
#define FILENAME "FILEC++.txt" void write()
{
ofstream ofs;//创建流对象
ofs.open(FILENAME, ios::out);//打开文件 ofs << "测试向FILEC++.txt中写文件" << endl;//写数据 ofs.close();//关闭文件
}
int main()
{
write(); return 0;
}打开 FILEC++.txt 查看文件内容变化。
你会发现,通过 ios::out 方式打开文件,之前的内容被覆盖了。
更改文件打开方式:
void write()
{
ofstream ofs;//创建流对象
ofs.open(FILENAME, ios::app);//打开文件 ofs << "测试向FILEC++.txt中写文件-2.0" << endl;//写数据 ofs.close();//关闭文件
}查看 FILEC++.txt 中的内容:
可以测试出, ios::app 是在原文件的基础上向后追加内容。
由于是通过创建 ofs 来进行写文件操作,那么原本的输出语句就不会报错。
#include<iostream>
#include<fstream>//包含头文件
using namespace std;
#define FILENAME "FILEC++.txt" void write()
{
ofstream ofs;//创建流对象
ofs.open(FILENAME, ios::out);//打开文件 ofs << "测试向FILEC++.txt中写文件" << endl;//写数据 ofs.close();//关闭文件
}
int main()
{
cout << "TEST1 : Hello World" << endl;
write();
cout << "TEST2 : Hello World" << endl;
return 0;
}运行结果:
FILEC++.txt :
可见,通过 ofstream 来进行写文件操作,并不会影响 cout 的输出。
读文件
步骤
- 创建流对象: ifstream ifs;
- 打开文件: ifs.open("文件路径",打开方式);
- 判断文件是否打开成功: ifs.is_open() (成功打开返回 true,否则返回 false)
- 读数据: ifs >> 变量1 >> 变量2 >> ...; (类比 cin)
- 关闭文件: ifs.close();
示例
在当前代码所在文件夹下新建一个 Input.txt 的文件,并放入如下数据:
分别代表:编号、姓名、年龄,并用 id , name , age 接受这三个数据。
#include<iostream>
#include<fstream>//包含头文件
using namespace std;
#define FILENAME "Input.txt" void read()
{
ifstream ifs;//创建流对象
ifs.open(FILENAME, ios::in);//打开文件 int id;
string name;
int age; if (!ifs.is_open())//判断文件是否打开成功
{
cout << "文件打开失败" << endl;
return;
} ifs >> id >> name >> age;//读数据,且 编号、姓名、年龄 要和文件中的数据保持一致
cout << "编号\t姓名\t年龄" << endl;
cout << id << "\t" << name << "\t" << age << endl; ifs.close();//关闭文件 return;
}
int main()
{
read(); return 0;
}运行结果:
C/C++ 文件读写的更多相关文章
- 【Win 10 应用开发】文件读写的三种方案
本文老周就跟伙伴们探讨一下关于文件读写的方法.总得来说嘛,有三种方案可以用,而且每种方案都各有特色,也说不上哪种较好.反正你得记住老祖宗留给我们的大智慧——事无定法,灵活运用者为上. OK,咱们开始吧 ...
- c语言文件读写操作总结
C语言文件读写操作总结 C语言文件操作 一.标准文件的读写 1.文件的打开 fopen() 文件的打开操作表示将给用户指定的文件在内存分配一个FILE结构区,并将该结构的指针返回给用户程序,以后用户程 ...
- ActionScript 3.0入门:Hello World、文件读写、数据存储(SharedObject)、与JS互调
近期项目中可能要用到Flash存取数据,并与JS互调,所以就看了一下ActionScript 3.0,现把学习结果分享一下,希望对新手有帮助. 目录 ActionScript 3.0简介 Hello ...
- Android 文件读写
一.分类 文件读写作为Android四大数据存储方式之一,又分为内部存储和外部存储两种: (1)内部存储(Internal storage): 总是可用. 文件默认情况存储在/data/data/包名 ...
- python基础之文件读写
python基础之文件读写 本节内容 os模块中文件以及目录的一些方法 文件的操作 目录的操作 1.os模块中文件以及目录的一些方法 python操作文件以及目录可以使用os模块的一些方法如下: 得到 ...
- 【Python】[IO编程]文件读写,StringIO和BytesIO,操作文件和目录,序列化
IO在计算机中指Input/Output,也就是输入和输出. 1.文件读写,1,读文件[使用Python内置函数,open,传入文件名标示符] >>> f = open('/User ...
- [转]Android - 文件读写操作 总结
转自:http://blog.csdn.net/ztp800201/article/details/7322110 Android - 文件读写操作 总结 分类: Android2012-03-05 ...
- Windows Phone 八、文件读写IO
文件存储的类型 •本地应用文件: •ApplicationData.Current.LocalFolder: •漫游应用文件: •ApplicationData.Current.RoamingFold ...
- Python之文件读写
本节内容: I/O操作概述 文件读写实现原理与操作步骤 文件打开模式 Python文件操作步骤示例 Python文件读取相关方法 文件读写与字符编码 一.I/O操作概述 I/O在计算机中是指Input ...
- JAVA之IO文件读写
IO概述: IO(Input output)流 作用:IO流用来处理设备之间的数据传输 ...
随机推荐
- .NET core实现一个简易的事件协调器(saga)
在领域驱动设计中,由于领域边界的存在,以往的分层设计中业务会按照其固有的领域知识被切分到不同的限界中,并且引入了领域事件这一概念来降低单个业务的复杂度,通过非耦合的事件驱动来完成复杂的业务.但是事件驱 ...
- 了解MySQL存储引擎工作原理
MySql数据库最大的特色就是其插件式的存储引擎架构,本文主要介绍MySql常用的存储引擎,为开发时选择合适的存储引擎提供参考. 1. MySql体系结构# 在介绍存储引擎之前先来介绍下MySql的体 ...
- Vue 源码解读(4)—— 异步更新
前言 上一篇的 Vue 源码解读(3)-- 响应式原理 说到通过 Object.defineProperty 为对象的每个 key 设置 getter.setter,从而拦截对数据的访问和设置. 当对 ...
- [题解]Codeforces Round #519 - D. Mysterious Crime
[题目] D. Mysterious Crime [描述] 有m个n排列,求一共有多少个公共子段. 数据范围:1<=n<=100000,1<=m<=10 [思路] 对于第一个排 ...
- 命名空间 namespace
命名空间是一块程序员可以自己命名的内存区域,用于解决同名冲突的问题. 举例来说,某班及内有三个张三,分别坐在班级的第一排.第三排和最后一排.当老师喊张三时,三个张三都站起来应答,这就是同名冲突 ...
- 【C#异常处理】堆栈溢出
栈溢出:死循环.递归调用,C# 的堆栈大小对于 32 位进程只有 1 MB,对于 64 位进程只有 4 MB如下: Main(args); static void Main(string[] args ...
- 【计算机基础】IL代码-CLR平台上的字节码【什么是字节码?它与虚拟机的关系?】
字节码(英语:Bytecode)将虚拟机可以读懂的代码称之为字节码.将源码编译成虚拟机读的懂的代码,需要虚拟机转译后才能成为机器代码的中间代码 叫做字节码. 字节码主要为了实现特定软件运行和软件环境. ...
- WebLogic服务器打补丁(11g/12c)
转至:https://segmentfault.com/a/1190000019059894 背景 2019年04月17日,Oracle发布新季度安全公告.该安全公告披露WebLogic服务器存在多个 ...
- MySql的事务及数据的导入导出
Mysql的事务及应用 1.补充数据库的导入与导出 导入 mysql -u root -p database < E:/SS/Test.sql -- 即执行sql文件 导出 -- 结构+数据 m ...
- git--撤销添加&放弃修改&代码冲突
git add . 后,撤销指定文件的add(还未提交): git reset HEAD 文件名 不保存本地改动,用远程代码覆盖: git reset --hard origin/dev 放弃工作区的 ...















