当前位置: 首页 > news >正文

C++017-C++文件读写应用

文章目录

  • C++017-C++文件读写应用
    • C++文件读写应用
      • CSP-J目标
      • 1. 文件的基本概念、文本文件的基本操作
      • 2.文本文件类型与二进制文件类型
        • 文本文件类型
        • 二进制文件类型
        • 二进制查看工具
      • 3.文件重定向、文件读写等操作
        • 关闭文件
        • 文件操作-写入文本文件
        • 文件操作-读取文本文件
        • 文件操作-写入二进制文件
        • 文件操作-读取二进制文件
        • 文件操作-随机存取
        • 文件操作-打开文件的模式(方式)
        • 文件操作-缓冲区及流状态
        • C++ 文件重定向
          • C++ 实现方法:
          • C++基于控制台实现重定向
          • C语言freopen()函数实现重定向
      • 2.文件读写操作
        • 基本案例
        • seekg() 和 tellg() 函数来读取文件中的数据
    • 在练习:
    • 总结

C++017-C++文件读写应用

在这里插入图片描述

在线练习:
http://noi.openjudge.cn/
https://www.luogu.com.cn/

C++文件读写应用

参考:
中文编码杂谈
https://space.bilibili.com/627875426
C++文件读写详解(ofstream,ifstream,fstream)

在这里插入图片描述

CSP-J目标

· 【 2 】文件的基本概念、文本文件的基本操作
· 【 2 】文本文件类型与二进制文件类型
· 【 2 】文件重定向、文件读写等操作

1. 文件的基本概念、文本文件的基本操作

在C++中,文件是一种数据存储方式,它可以是文本文件或二进制文件。文本文件是以文本格式存储数据的文件,每个字符都被存储为其ASCII码值的文本文件,可以用普通的文本编辑器打开和编辑。在C++中,可以使用标准库中的文件流来打开、读取、写入和关闭文件。

打开文件:使用文件流对象(例如 ifstream 或 ofstream)创建一个文件对象并打开文件。打开文件时,可以指定打开模式,例如只读、只写、追加等模式。
读取文件:使用输入流对象(例如 ifstream)从文件中读取数据。可以使用不同的读取函数,例如 getline、get、read等。要读取文件,必须先打开文件。
写入文件:使用输出流对象(例如 ofstream)向文件中写入数据。可以使用不同的写入函数,例如 put、write、<< 运算符等。要写入文件,必须先打开文件。
关闭文件:使用文件流对象的 close() 函数关闭文件。关闭文件后,不能再对其进行读取或写入操作。
在这里插入图片描述

#include <fstream>  
ofstream         //文件写操作 内存写入存储设备 (由ostream引申而来)   
ifstream         //文件读操作,存储设备读区到内存中  (由ostream引申而来) 
fstream          //读写操作,对打开的文件可进行读写操作  (由iostream引申而来) 

2.文本文件类型与二进制文件类型

参考:https://www.cnblogs.com/xkfz007/archive/2011/07/21/2176994.html
在这里插入图片描述在这里插入图片描述

在这里插入图片描述

文本文件类型

txt是纯文本格式,简单来说就是没有格式的普通文本文件;csv是逗号分隔值文件,用逗号分隔数据字段;json是一种轻量级的数据交换格式,以键值对的形式存储数据;xml是可扩展标记语言,用于存储和传输数据;html是超文本标记语言,用于创建网页和其他可视化浏览器界面的文件格式。

二进制文件类型

二进制文件类型有很多种,其中常见的有以下几种:
可执行文件:一般是以.exe为后缀名的文件,可以直接运行。
动态链接库(DLL):一般是以.dll为后缀名的文件,它是一种动态链接库文件,包含一些被程序调用的函数和数据。
静态链接库(LIB):一般是以.lib为后缀名的文件,它也是一种库文件,但是不同于DLL文件,它在编译时被链接到程序中。
数据文件:一般是以.dat、.bin等后缀名的文件,里面存放着程序需要的数据。
图像文件:一般是以.bmp、.jpg、.png等后缀名的文件,存储着图像的二进制数据。
音频文件:一般是以.mp3、.wav等后缀名的文件,存储着音频的二进制数据。
举例说明,例如.exe文件就是一种二进制文件,它可以直接执行,例如:游戏中的游戏客户端。DLL文件则是一种动态链接库,例如:Windows系统中的一些系统DLL文件。LIB文件则是一种静态链接库文件,例如:开发中使用的一些通用库。而图像文件、音频文件等等,它们都是二进制数据的存储方式。

二进制查看工具

一个文件,内容如下:

ABCD
abcd

用Binary Viewer打开
在这里插入图片描述

Hexadecimal是字节流内容,右侧是字符流内容。Hexadecimal中的内容形式是十六进制数,因为字符在操作系统中存储的形式是ASCII码值,所以左侧红框里的数值是的十六进制形式的ASCII码值,右侧是该ASCII码值对应的字符内容。。比如左侧第一个十六进制数字是41,其对应的十进制是4*16 + 1=65,在ASCII码表中65对应的是A,如上图右侧框中的第一个字母所示。下方给出ASCII码表。
在这里插入图片描述

3.文件重定向、文件读写等操作

关闭文件

当文件读写操作完成之后,我们必须将文件关闭以使文件重新变为可访问的。成员函数close(),它负责将缓存中的数据排放出来并关闭文件。这个函数一旦被调用,原先的流对象就可以被用来打开其它的文件了,这个文件也就可以重新被其它的进程所访问了。为防止流对象被销毁时还联系着打开的文件,析构函数将会自动调用关闭函数close。

文件操作-写入文本文件

文本文件一般以行的形式组织数据。
在fstream类中,成员函数open()实现打开文件的操作,从而将数据流和文件进行关联,通过ofstream,ifstream,fstream对象进行对文件的读写操作

函数:open()

 
public member functionvoid open ( const char * filename,ios_base::openmode mode = ios_base::in | ios_base::out );void open(const wchar_t *_Filename,ios_base::openmode mode= ios_base::in | ios_base::out,int prot = ios_base::_Openprot)

打开文件的方式在ios类(所以流式I/O的基类)中定义,有如下几种方式:
在这里插入图片描述

包含头文件:#include <fstream>
类:ofstream(output file stream)

ofstream打开文件的模式(方式):
对于ofstream,不管用哪种模式打开文件,如果文件不存在,都会创建文件。
ios::out 缺省值:会截断文件内容。
ios::trunc 截断文件内容。(truncate)
ios::app 不截断文件内容,只在文件未尾追加文件。(append)

示例:

#include <iostream>
#include <fstream>  // ofstream类需要包含的头文件。
using  namespace std;int main()
{// 文件名一般用全路径,书写的方法如下://  1)"D:\data\txt\test.txt"       // 错误。//  2)R"(D:\data\txt\test.txt)"   // 原始字面量,C++11标准。//  3)"D:\\data\\txt\\test.txt"   // 转义字符。//  4)"D:/tata/txt/test.txt"        // 把斜线反着写。//  5)"/data/txt/test.txt"          //  Linux系统采用的方法。string filename = R"(D:\data\txt\test.txt)";//char    filename[] = R"(D:\data\txt\test.txt)";// 创建文件输出流对象,打开文件,如果文件不存在,则创建它。// ios::out     		缺省值:会截断文件内容。// ios::trunc  		截断文件内容。(truncate)// ios::app   			不截断文件内容,只在文件未尾追加文件。(append)//ofstream fout(filename);//ofstream fout(filename, ios::out);//ofstream fout(filename, ios::trunc);//ofstream fout(filename, ios::app);ofstream fout;fout.open(filename,ios::app);// 判断打开文件是否成功。// 失败的原因主要有:1)目录不存在;2)磁盘空间已满;3)没有权限,Linux平台下很常见。if (fout.is_open() == false){cout << "打开文件" << filename << "失败。\n";  return 0;}// 向文件中写入数据。fout << "你好 淄博1\n";fout << "你好 淄博2\n";fout << "你好 淄博3\n";fout.close();	   // 关闭文件,fout对象失效前会自动调用close()。cout << "操作文件完成。\n";
}

文件操作-读取文本文件

包含头文件:#include <fstream>
类:ifstream

ifstream打开文件的模式(方式):
对于ifstream,如果文件不存在,则打开文件失败。
ios::in 缺省值。

示例:

#include <iostream>
#include <fstream>  // ifstream类需要包含的头文件。
#include <string>     // getline()函数需要包含的头文件。
using  namespace std;int main()
{// 文件名一般用全路径,书写的方法如下://  1)"D:\data\txt\test.txt"       // 错误。//  2)R"(D:\data\txt\test.txt)"   // 原始字面量,C++11标准。//  3)"D:\\data\\txt\\test.txt"   // 转义字符。//  4)"D:/tata/txt/test.txt"        // 把斜线反着写。//  5)"/data/txt/test.txt"          //  Linux系统采用的方法。string filename = R"(D:\data\txt\test.txt)";//char    filename[] = R"(D:\data\txt\test.txt)";// 创建文件输入流对象,打开文件,如果文件不存在,则打开文件失败。。// ios::in     			缺省值。//ifstream fin(filename);//ifstream fin(filename, ios::in);ifstream fin;fin.open(filename,ios::in);// 判断打开文件是否成功。// 失败的原因主要有:1)目录不存在;2)文件不存在;3)没有权限,Linux平台下很常见。if (fin.is_open() == false){cout << "打开文件" << filename << "失败。\n";  return 0;} 第一种方法。//string buffer;  // 用于存放从文件中读取的内容。 文本文件一般以行的方式组织数据。//while (getline(fin, buffer))//{//	cout << buffer << endl;//} 第二种方法。//char buffer[16];   // 存放从文件中读取的内容。 注意:如果采用ifstream.getline(),一定要保证缓冲区足够大。//while (fin.getline(buffer, 15))//{//	cout << buffer << endl;//}// 第三种方法。string buffer;// 析取器(>>),>>遇到空格、换行符后停止读取文件,待再次调用时才接着读取。可以理解为>>不读空格、换行符while (fin >> buffer){cout << buffer << endl;}fin.close();	   // 关闭文件,fin对象失效前会自动调用close()。cout << "操作文件完成。\n";
}

在这里插入图片描述

文件操作-写入二进制文件

二进制文件以数据块的形式组织数据,把内存中的数据直接写入文件。

包含头文件:#include <fstream>
类:ofstream(output file stream)

ofstream打开文件的模式(方式):
对于ofstream,不管用哪种模式打开文件,如果文件不存在,都会创建文件。

ios::out 缺省值:会截断文件内容。
ios::trunc 截断文件内容。(truncate)
ios::app 不截断文件内容,只在文件未尾追加文件。(append)
ios::binary 以二进制方式打开文件。

操作文本文件和二进制文件的一些细节:

1)在windows平台下,文本文件的换行标志是"\r\n"。
2)在linux平台下,文本文件的换行标志是"\n"。
3)在windows平台下,如果以文本方式打开文件,写入数据的时候,系统会将"\n"转换成"\r\n";读取数据的时候,系统会将"\r\n"转换成"\n"。 如果以二进制方式打开文件,写和读都不会进行转换。
4)在Linux平台下,以文本或二进制方式打开文件,系统不会做任何转换。
5)以文本方式读取文件的时候,遇到换行符停止,读入的内容中没有换行符;以二制方式读取文件的时候,遇到换行符不会停止,读入的内容中会包含换行符(换行符被视为数据)。
6)在实际开发中,从兼容和语义考虑,一般:a)以文本模式打开文本文件,用行的方法操作它;b)以二进制模式打开二进制文件,用数据块的方法操作它;c)以二进制模式打开文本文件和二进制文件,用数据块的方法操作它,这种情况表示不关心数据的内容。(例如复制文件和传输文件)d)不要以文本模式打开二进制文件,也不要用行的方法操作二进制文件,可能会破坏二进制数据文件的格式,也没有必要。(因为二进制文件中的某字节的取值可能是换行符,但它的意义并不是换行,可能是整数n个字节中的某个字节)

示例:

#include <iostream>
#include <fstream>  // ofstream类需要包含的头文件。
using  namespace std;int main()
{// 文件名一般用全路径,书写的方法如下://  1)"D:\data\bin\test.dat"       // 错误。//  2)R"(D:\data\bin\test.dat)"   // 原始字面量,C++11标准。//  3)"D:\\data\\bin\\test.dat"   // 转义字符。//  4)"D:/tata/bin/test.dat"        // 把斜线反着写。//  5)"/data/bin/test.dat"          //  Linux系统采用的方法。string filename = R"(.\test.dat)";//char    filename[] = R"(D:\data\bin\test.dat)";// 创建文件输出流对象,打开文件,如果文件不存在,则创建它。// ios::out     		缺省值:会截断文件内容。// ios::trunc  		截断文件内容。(truncate)// ios::app   			不截断文件内容,只在文件未尾追加文件。(append)// ios::binary   		以二进制方式打开文件。//ofstream fout(filename, ios::binary);//ofstream fout(filename, ios::out | ios::binary);//ofstream fout(filename, ios::trunc | ios::binary);//ofstream fout(filename, ios::app | ios::binary);ofstream fout;fout.open(filename, ios::app | ios::binary);// 判断打开文件是否成功。// 失败的原因主要有:1)目录不存在;2)磁盘空间已满;3)没有权限,Linux平台下很常见。if (fout.is_open() == false){cout << "打开文件" << filename << "失败。\n";  return 0;}// 向文件中写入数据。struct st_girl {               // 超女结构体。char name[31];         // 姓名。int    no;                    // 编号。char memo[301];      // 备注。double weight;         // 体重。};struct st_girl girl = { "西施",3,"中国历史第一美女。" ,45.8 };fout.write((const char *)& girl, sizeof(st_girl));   // 写入第一块数据。struct st_girl girl2 = { "冰冰",8,"也是个大美女哦。",55.2};fout.write((const char*)&girl2, sizeof(st_girl));     // 写入第二块数据。fout.close();	   // 关闭文件,fout对象失效前会自动调用close()。cout << "操作文件完成。\n";
}

文件操作-读取二进制文件

包含头文件:#include <fstream>
类:ifstream

ifstream打开文件的模式(方式):
对于ifstream,如果文件不存在,则打开文件失败。
ios::in 缺省值。
ios::binary 以二进制方式打开文件。

示例:

#include <iostream>
#include <fstream>  // ifstream类需要包含的头文件。
using  namespace std;int main()
{// 文件名一般用全路径,书写的方法如下://  1)"D:\data\bin\test.dat"       // 错误。//  2)R"(D:\data\bin\test.dat)"   // 原始字面量,C++11标准。//  3)"D:\\data\\bin\\test.dat"   // 转义字符。//  4)"D:/tata/bin/test.dat"        // 把斜线反着写。//  5)"/data/bin/test.dat"          //  Linux系统采用的方法。string filename = R"(.\test.dat)";//char    filename[] = R"(D:\data\bin\test.dat)";// 创建文件输入流对象,打开文件,如果文件不存在,则打开文件失败。。// ios::in     			缺省值。// ios::binary   		以二进制方式打开文件。//ifstream fin(filename , ios::binary);//ifstream fin(filename , ios::in | ios::binary);ifstream fin;fin.open(filename, ios::in | ios::binary);// 判断打开文件是否成功。// 失败的原因主要有:1)目录不存在;2)文件不存在;3)没有权限,Linux平台下很常见。if (fin.is_open() == false){cout << "打开文件" << filename << "失败。\n";  return 0;}// 二进制文件以数据块(数据类型)的形式组织数据。struct st_girl {               // 超女结构体。char name[31];         // 姓名。int    no;                    // 编号。   char memo[301];      // 备注。double weight;         // 体重。}girl;while (fin.read((char*)&girl, sizeof(girl))){cout << "name=" << girl.name << ",no=" << girl.no << ",memo=" << girl.memo << ",weight=" << girl.weight << endl;}fin.close();	   // 关闭文件,fin对象失效前会自动调用close()。cout << "操作文件完成。\n";
}

在这里插入图片描述

文件操作-随机存取

一、fstream类
fstream类既可以读文本/二进制文件,也可以写文本/二进制文件。
fstream类的缺省模式是ios::in | ios::out,如果文件不存在,则创建文件;但是,不会清空文件原有的内容。
普遍的做法是:
1)如果只想写入数据,用ofstream;如果只想读取数据,用ifstream;如果想写和读数据,用fstream,这种情况不多见。不同的类体现不同的语义。
2)在Linux平台下,文件的写和读有严格的权限控制。(需要的权限越少越好)
二、文件的位置指针
对文件进行读/写操作时,文件的位置指针指向当前文件读/写的位置。
很多资料用“文件读指针的位置”和“文件写指针的位置”,容易误导人。不管用哪个类操作文件,文件的位置指针只有一个。
1)获取文件位置指针
ofstream类的成员函数是tellp();ifstream类的成员函数是tellg();fstream类两个都有,效果相同。

std::streampos tellp();
std::streampos tellg();

2)移动文件位置指针
ofstream类的函数是seekp();ifstream类的函数是seekg();fstream类两个都有,效果相同。
方法一:

std::istream & seekg(std::streampos _Pos);  
fin.seekg(128);   // 把文件指针移到第128字节。
fin.seekp(128);   // 把文件指针移到第128字节。
fin.seekg(ios::beg) // 把文件指针移动文件的开始。
fin.seekp(ios::end) // 把文件指针移动文件的结尾。

方法二:

std::istream & seekg(std::streamoff _Off,std::ios::seekdir _Way);

在ios中定义的枚举类型:
enum seek_dir {beg, cur, end}; // beg-文件的起始位置;cur-文件的当前位置;end-文件的结尾位置。

fin.seekg(30, ios::beg);    // 从文件开始的位置往后移30字节。
fin.seekg(-5, ios::cur);     // 从当前位置往前移5字节。
fin.seekg( 8, ios::cur);     // 从当前位置往后移8字节。
fin.seekg(-10, ios::end);   // 从文件结尾的位置往前移10字节。

三、随机存取
随机存取是指直接移动文件的位置指针,在指定位置读取/写入数据。

示例:

#include <iostream>
#include <fstream>  // fstream类需要包含的头文件。
using  namespace std;int main()
{string filename = R"(D:\data\txt\test.txt)";fstream fs;fs.open(filename, ios::in | ios::out);if (fs.is_open() == false){cout << "打开文件" << filename << "失败。\n";  return 0;}fs.seekg(26);    // 把文件位置指针移动到第26字节处。fs << "我是一只傻傻的小菜鸟。\n"; /*string buffer; while (fs >> buffer){cout << buffer << endl;}*/fs.close();	   // 关闭文件,fs对象失效前会自动调用close()。cout << "操作文件完成。\n";
}

在这里插入图片描述

文件操作-打开文件的模式(方式)

一、写文件
如果文件不存在,各种模式都会创建文件。

ios::out     		1)会截断文件;2)可以用seekp()移动文件指针。
ios:trunc  		1)会截断文件;2)可以用seekp()移动文件指针。
ios::app   		1)不会截断文件;2)文件指针始终在文件未尾,不能用seekp()移动文件指针。
ios::ate    		打开文件时文件指针指向文件末尾,但是,可以在文件中的任何地方写数据。
ios::in        		打开文件进行读操作,即读取文件中的数据。
ios::binary       	打开文件为二进制文件,否则为文本文件。

注:ate是at end的缩写,trunc是truncate(截断)的缩写,app是append(追加)的缩写。

文件操作-缓冲区及流状态

一、文件缓冲区
文件缓冲区(缓存)是系统预留的内存空间,用于存放输入或输出的数据。
根据输出和输入流,分为输出缓冲区和输入缓冲区。
注意,在C++中,每打开一个文件,系统就会为它分配缓冲区。不同的流,缓冲区是独立的。
程序员不用关心输入缓冲区,只关心输出缓冲区就行了。
在缺省模式下,输出缓冲区中的数据满了才把数据写入磁盘,但是,这种模式不一定能满足业务的需求。
输出缓冲区的操作:
1)flush()成员函数
刷新缓冲区,把缓冲区中的内容写入磁盘文件。
2)endl
换行,然后刷新缓冲区。
3)unitbuf
fout << unitbuf;
设置fout输出流,在每次操作之后自动刷新缓冲区。
4)nounitbuf
fout << nounitbuf;
设置fout输出流,让fout回到缺省的缓冲方式。
二、流状态
流状态有三个:eofbit、badbit和failbit,取值:1-设置;或0-清除。
当三个流状成都为0时,表示一切顺利,good()成员函数返回true。
1)eofbit
当输入流操作到达文件未尾时,将设置eofbit。
eof()成员函数检查流是否设置了eofbit。
2)badbit
无法诊断的失败破坏流时,将设置badbit。(例如:对输入流进行写入;磁盘没有剩余空间)。
bad()成员函数检查流是否设置了badbit。
3)failbit
当输入流操作未能读取预期的字符时,将设置failbit(非致命错误,可挽回,一般是软件错误,例如:想读取一个整数,但内容是一个字符串;文件到了未尾)I/O失败也可能设置failbit。
fail()成员函数检查流是否设置了failbit。
4)clear()成员函数清理流状态。
5)setstate()成员函数重置流状态。
示例1:

#include <iostream>
#include <fstream>          // ofstream类需要包含的头文件。
#include<windows.h> //window下的Sleep
//#include <unistd.h> // linux下的 usleep(100000)
using  namespace std;int main()
{ofstream fout("./bbb.txt");   // 打开文件。fout << unitbuf;for (int ii = 0; ii < 100; ii++)  // 循环1000次。{fout << "ii=" << ii << ",我是一只傻傻傻傻傻傻傻傻傻傻傻傻傻傻的鸟。\n";//fout.flush();      // 刷新缓冲区。//usleep(100000);    // 睡眠十分之一秒 linux下。Sleep(1);}fout.close();  // 关闭文件。
}

在这里插入图片描述

示例2:

#include <iostream>
#include <fstream>  // ifstream类需要包含的头文件。
#include <string>     // getline()函数需要包含的头文件。
using  namespace std;int main()
{ifstream fin(R"(D:\data\txt\test.txt)", ios::in);if (fin.is_open() == false) {cout << "打开文件" << R"(D:\data\txt\test.txt)" << "失败。\n";  return 0;}string buffer;/*while (fin >> buffer) {cout << buffer << endl;}*/while (true) {fin >> buffer;cout << "eof()=" << fin.eof() << ",good() = " << fin.good() << ", bad() = " << fin.bad() << ", fail() = " << fin.fail() << endl;if (fin.eof() == true) break;cout << buffer << endl;}fin.close();	   // 关闭文件,fin对象失效前会自动调用close()。
}

在这里插入图片描述

C++ 文件重定向

<一>、简单的理解重定向:

就是:

把 原来的 cin 从键盘输入 改为从文件输入。
把 原来的 cout 向屏幕输出 改为输出到文件。
例如: cin>>line; 原来要从键盘拍入。现在自动到某文件读取,语句还是 cin>>line; 不变。
cout << line << endl; 原来向屏幕输出,现在自动写到某文件里,语句还是cout << line << endl;不变
=======

C++ 实现方法:

rdbuf() 函数定义在<ios>头文件中,专门用于实现 C++ 输入输出流的重定向。

值得一提的是,ios 作为 istream 和 ostream 类的基类,rdbuf() 函数也被继承,因此 cin 和 cout 可以直接调用该函数实现重定向.
rdbuf() 函数的语法格式有 2 种,分别为:

streambuf * rdbuf() const;
streambuf * rdbuf(streambuf * sb);

streambuf 是 C++ 标准库中用于表示缓冲区的类,该类的指针对象用于代指某个具体的流缓冲区。
其中,第一种语法格式仅是返回一个指向当前流缓冲区的指针;第二种语法格式用于将 sb 指向的缓冲区设置为当前流的新缓冲区,并返回一个指向旧缓冲区的对象。

案例1:

#include <iostream>
#include <fstream>
using namespace std;
int main()
{//打开 in.txt 文件,等待读取ifstream fin("test.txt");//打开 out.txt 文件,等待写入ofstream fout("out.txt");streambuf *oldcin;streambuf *oldcout;char a[100];//用 rdbuf() 重新定向,返回旧输入流缓冲区指针oldcin = cin.rdbuf(fin.rdbuf());//用 rdbuf() 重新定向,返回旧输出流缓冲区指针oldcout = cout.rdbuf(fout.rdbuf());//从input.txt文件读入while (cin >> a){//写入 out.txtcout << a << endl;}//还原标准输入输出流cin.rdbuf(oldcin); // 恢复键盘输入cout.rdbuf(oldcout); //恢复屏幕输出//打开的文件,最终需要手动关闭fin.close();fout.close();return 0;

案例2:

#include <iostream>
#include <ostream>
#include <fstream>
using namespace std;
main()
{
ifstream fin("./test.txt"); // 已有输入文件
ofstream fout("./output.txt"); //输出文件
streambuf *cinbackup;
streambuf *coutbackup;
coutbackup= cout.rdbuf(fout.rdbuf()); //用 rdbuf() 重新定向
cinbackup= cin.rdbuf(fin.rdbuf()); //用 rdbuf() 重新定向
cout<<"Hello world"<<endl; //去文件也
char line[100];
while (cin>>line){ //从input.txt文件读入cout<<line<<endl; //写入 output.txt
};// restore standard streambuf
cin.rdbuf(cinbackup); // 取消,恢复键盘输入
cout.rdbuf(coutbackup); //取消,恢复屏幕输出
return 0;
}

在这里插入图片描述

C++基于控制台实现重定向

C++通过控制台实现重定向
以上 2 种方法,都是从代码层面实现输入输出流的重定向。除此之外,我们还可以通过控制台实现输入输出的重定向。

#include <iostream>
#include <string>
using namespace std;
int main()
{string name, url;cin >> name >> url;cout << name << '\n' << url;return 0;
}

编译运行后,在debug目录下生成
D:\cplusproject\day0305\bin\Debug\day0305.exe

在D:\cplusproject\day0305\bin\Debug中创建a.txt

你好啊
啊阿达fd
dfdf
12

运行:

day0305.exe <a.txt >b.txt

生成b.txt

你好啊
啊阿达fd

C语言freopen()函数实现重定向

freopen() 定义在<stdio.h>头文件中,是 C 语言标准库中的函数,专门用于重定向输入流(包括 scanf()、gets() 等)和输出流(包括 printf()、puts() 等)。值得一提的是,该函数也可以对 C++ 中的 cin 和 cout 进行重定向。

#include <iostream>    //cin、cout
#include <string>      //string
#include <stdio.h>     //freopen
using namespace std;
int main()
{string name, url;//将标准输入流重定向到 in.txt 文件freopen("test.txt", "r", stdin);cin >> name >> url;//将标准输出重定向到 out.txt文件freopen("out.txt", "w", stdout);cout << name << "\n" << url;return 0;
}

在这里插入图片描述

2.文件读写操作

基本案例

#include <iostream>
#include <fstream>using namespace std;int main() {// 打开文件ofstream outfile("data.txt");if (!outfile.is_open()) {cout << "无法打开文件" << endl;return 1;}// 写入数据outfile << "Hello, world!" << endl;outfile << "Hello, world222" << endl;// 关闭文件outfile.close();// 重新打开文件ifstream infile("data.txt");if (!infile.is_open()) {cout << "无法打开文件" << endl;return 1;}// 读取数据string line;
//    getline(infile, line);
//    cout << line << endl;while (getline(infile,line)){cout<<line<<endl;}// 关闭文件infile.close();return 0;
}

在这里插入图片描述

seekg() 和 tellg() 函数来读取文件中的数据

判断文件是否打开:可以使用文件流对象的 is_open() 函数来判断文件是否成功打开。如果打开成功,该函数将返回 true,否则返回 false。
获取文件位置:可以使用输入流对象的 tellg() 函数获取当前的读取位置,使用输出流对象的 tellp() 函数获取当前的写入位置。这些函数返回的值是一个指针,指向当前位置的字节偏移量。
移动文件位置:可以使用输入流对象的 seekg() 函数和输出流对象的 seekp() 函数移动读取或写入位置。这些函数的第一个参数是一个指针,指定要移动的位置的字节偏移量,第二个参数指定相对于哪个位置进行移动,例如 ios::beg(文件开头)、ios::cur(当前位置)或 ios::end(文件末尾)。
判断文件结束:可以使用输入流对象的 eof() 函数判断是否已经到达文件末尾。如果已经到达文件末尾,该函数将返回 true,否则返回 false。

#include <iostream>
#include <fstream>using namespace std;int main() {// 打开文件ofstream outfile("data.txt");if (!outfile.is_open()) {cout << "无法打开文件" << endl;return 1;}// 写入数据//outfile << "Hello, world!" << endl;outfile << "Hello, world!1" << endl;outfile << "Hello, world!1"<<endl;// 关闭文件outfile.close();// 打开文件ifstream infile("data.txt");if (!infile.is_open()) {cout << "无法打开文件" << endl;return 1;}// 获取文件大小infile.seekg(0, ios::end);int length = infile.tellg();infile.seekg(0, ios::beg);cout<<"长度为:"<<length<<endl;// 读取数据char* buffer = new char[length+1];cout<<"buffer长度为:"<<sizeof(buffer)<<endl;infile.read(buffer, length);buffer[length] = '\0';// 输出数据cout << buffer << endl;// 释放内存并关闭文件delete[] buffer;infile.close();return 0;
}

在这里插入图片描述

在练习:

http://noi.openjudge.cn/

总结

本系列为C++学习系列,会介绍C++基础语法,基础算法与数据结构的相关内容。本文为C++文件读写应用案例,包括相关案例练习。

相关文章:

C++017-C++文件读写应用

文章目录 C017-C文件读写应用C文件读写应用CSP-J目标1. 文件的基本概念、文本文件的基本操作2.文本文件类型与二进制文件类型文本文件类型二进制文件类型二进制查看工具 3.文件重定向、文件读写等操作关闭文件文件操作-写入文本文件文件操作-读取文本文件文件操作-写入二进制文…...

计算机网络 实验二

⭐计网实验专栏&#xff0c;欢迎订阅与关注&#xff01; ★观前提示&#xff1a;本篇内容为计算机网络实验。内容可能会不符合每个人实验的要求&#xff0c;因此以下内容建议仅做思路参考。 一、实验目的 &#xff08;1&#xff09;掌握IP地址的基本结构(网络部分与主机部分的…...

Unity 3D 学习笔记(1)

文章目录 1.Unity 3D 概述2.Unity的安装过程3.Unity 3D 的项目管理4.Unity 3D 中的场景5.Unity 3D 的界面组成 1.Unity 3D 概述 Unity 3D简介&#xff1a;Unity 3D是虚拟现实行业中使用率较高的一款开发引擎&#xff0c;由Unity Technology公司开发。通过Unity&#xff0c;开发…...

P1050 [NOIP2005 普及组] 循环

题目描述 乐乐是一个聪明而又勤奋好学的孩子。他总喜欢探求事物的规律。一天&#xff0c;他突然对数的正整数次幂产生了兴趣。 众所周知&#xff0c;22 的正整数次幂最后一位数总是不断的在重复 2,4,8,6,2,4,8,6…2,4,8,6,2,4,8,6… 我们说 22 的正整数次幂最后一位的循环长度…...

软考算法-排序篇-上

数据排序 一&#xff1a;故事背景二&#xff1a;直接插入排序2.1 概念2.2 画图表示2.3 代码实现2.4 总结提升 三&#xff1a;希尔排序3.1 概念3.2 画图表示3.3 代码实现3.4 总结提升 四&#xff1a;直接选择排序4.1 概念4.2 画图表示4.3 代码实现4.4 总结提升 五&#xff1a;堆…...

总结836

学习目标&#xff1a; 4月&#xff08;复习完高数18讲内容&#xff0c;背诵21篇短文&#xff0c;熟词僻义300词基础词&#xff09; 学习内容&#xff1a; 暴力英语&#xff1a;背诵《keep your direction》&#xff0c;默写&#xff0c;英语语法 高等数学&#xff1a;刷题&a…...

ginbuilder 工具快速创建

ginbuilder github 地址 快速创建一个ginweb项目&#xff1a; 目前apps下只有http服务&#xff0c;如果后续有需要的话&#xff0c;会添加上rpc服务&#xff0c;websocket服务后边如果有需要会添加上swagger 创建完成的目录结构 ├── apps │ ├── apis // 所有的apis…...

【Java基础面试宝典】堆、栈、方法区分别都存储了那些内容?wait 和 sleep 方法的区别?

目录 堆、栈、方法区分别都存储了那些内容&#xff1f; 堆&#xff08;heap&#xff09; 栈&#xff08;stack&#xff09; 方法区&#xff08;method&#xff09; 在 java 中 wait 和 sleep 方法的区别&#xff1f; 堆、栈、方法区分别都存储了那些内容&#xff1f; 堆&a…...

古剑飞仙手游Linux系统服务器架设教程

安装宝塔直接运行命令即可。 yum install -y wget && wget -O install.sh http://download.bt.cn/install/install_6.0.sh && sh install.sh 搭建环境&#xff1a; centos 7以上系统服务器 宝塔面板安装应用如下&#xff1a; Nginx1.14 mysql5.7 php5.6 1…...

python实战应用讲解-【numpy数组篇】常用函数(十)(附python示例代码)

目录 Python Numpy MaskedArray.ravel()函数 Python Numpy MaskedArray.reshape()函数 Python Numpy MaskedArray.resize()函数 Python Numpy MaskedArray.std()函数 Python Numpy MaskedArray.sum()函数 Python Numpy MaskedArray.swapaxes()函数 Python Numpy MaskedA…...

计算机组成原理(考研408)练习题#2

用于复习408或计算机组成原理期末考试。如有错误请在评论区指出。 So lets start studying with questions! それでは、問題の勉強を始めましょう&#xff01; 11.某 cache 采用全相联映射&#xff0c;假设 cache 有 3 块&#xff0c;程序运行过程中需要访问的主存块号依 次为…...

Apache POI,springboot中导出excel报表

2. Apache POI 2.1 介绍 Apache POI 是一个处理Miscrosoft Office各种文件格式的开源项目。简单来说就是&#xff0c;我们可以使用 POI 在 Java 程序中对Miscrosoft Office各种文件进行读写操作。 一般情况下&#xff0c;POI 都是用于操作 Excel 文件。 Apache POI 的应用场景…...

CSS(一)-- 三种样式表

目录 1. 行内样式表 2. 内部样式表 3. 外部样式表&#xff08;即引入 .css文件&#xff09;&#xff08;重点掌握&#xff09; 1. 行内样式表 行内样式表&#xff08;内联样式表&#xff09;是在元素标签内部的 style 属性中设定 CSS 样式。适合于修改简单样式。 <di…...

嵌入式之Samba服务器搭建

在嵌入式系统开发应用平台中&#xff0c;tftp、nfs和samba服务器是最常用的文件传输工具 tftp和nfs是在嵌入式Linux开发环境中经常使用的传输工具 samba则是Linux和Windows之间的文件传输工具。 下面演示在linux上搭建Samba服务器 sudo apt-get install samba chmod -R 77…...

vue3+go——看到了就去学习吧

vue3go——看到了就去学习吧 Vue3.2 Vite Element-Plus 实现最基础的 CRUD1.效果展示【02:36】2.创建项目【03:16】3.添加github管理【04:10】4.引入element-plus【04:21】5.内容布局【08:59】6.布局优化【05:31】7.添加弹窗【09:34】8.ref改$ref【02:47】9.新增数据【09:22】…...

Perf工具统计CPU性能

Perf 性能检测工具 Perf 是一个内置于Linux内核中的工具&#xff0c;用于性能分析和调优。它可以对系统的CPU使用情况、内存使用情况、磁盘I/O、网络I/O等进行监控和分析&#xff0c;并提供了丰富的分析和可视化工具&#xff0c;以帮助用户定位和解决性能问题。perf可以进行函…...

考验大家指针功底的时候到了:请问如何理解 (int*)1 + 1 ?

来&#xff0c;猜猜看&#xff0c;这里的执行结果是什么&#xff1f; 这是今天课上的一道理解题&#xff0c;给大家一点点思考时间。 &#xff08;心里有答案了再往下滑哦&#xff09; 5 4 3 2 1 . 答案是&#xff0c;报warning&#xff01;因为%d不是用来输出指针的哈…...

英语基础-介词

介词 方位介词 in:在…里面 Its in the box. 在盒子里 in my backpack 在背包里 in the tree 长在树上on:在…上面&#xff08;指与物体表面接触&#xff09; Its on the box. 在盒子上(和盒子接触) on the floor.在地板上 on the tree.在树上under:在…下面 Its unde…...

Linux进程通信:进程组 会话

1. 进程组 &#xff08;1&#xff09;概念&#xff1a;一个或多个进程的集合&#xff0c;也称为“作业”。 &#xff08;2&#xff09;父进程创建子进程时&#xff0c;默认属于同一个进程组。进程组ID为组长进程ID。 &#xff08;3&#xff09;进程组中只要有一个进程存在&a…...

【前端面经】JS-深浅拷贝

理解深浅拷贝 深浅拷贝问题的出现是由于JavaScript对不同类型的存储方式而引发的。 对于原始数据类型&#xff0c;它们的值是直接存储在栈内存中&#xff1b; 而复杂数据类型&#xff0c;则在栈内存中记录它的指针&#xff0c;而指针指向堆内存中真正的值。 所以对于原始数据类…...

【自然语言处理】实验2布置:Word2Vec TransE案例

NLP_class 学堂在线《自然语言处理》实验课代码报告&#xff0c;授课老师为刘知远老师。课程链接&#xff1a;https://www.xuetangx.com/training/NLP080910033761/1017121?channeli.area.manual_search。 持续更新中。 所有代码为作者所写&#xff0c;并非最后的“标准答案…...

Redis集合底层实现原理

目录 本章重点简单动态字符串SDS集合底层实现原理zipListlistPackskipListquickListKey 与Value中元素的数量 本章重点 掌握Redis简单动态字符串了解Redis集合底层实现原理 简单动态字符串SDS SDS简介 我们Redis中无论是key还是value其数据类型都是字符串.我们Redis中的字符…...

OVS常用命令与使用总结

OVS常用命令与使用总结 说明 在平时使用ovs中&#xff0c;经常用到的ovs命令&#xff0c;参数&#xff0c;与举例总结&#xff0c;持续更新中… 进程启动 1.先准备ovs的工作目录&#xff0c;数据库存储路径等 mkdir -p /etc/openvswitch mkdir -p /var/run/openvswitch …...

一以贯之:从城市网络到“城市一张网”

《论语里仁》中子曰&#xff1a;“参乎&#xff0c;吾道一以贯之”。 孔子所说的“一以贯之”&#xff0c;逐渐成为了中国文化与哲学的重要组成部分&#xff0c;指明事物发展往往需要以标准化、集约化、融合化作为目标。这种智慧在数字化发展中格外重要。从云计算、大数据技术模…...

【Java校招面试】基础知识(四)——JVM

目录 前言一、基础概念二、反射三、类加载器ClassLoader四、JVM内存模型后记 前言 本篇主要介绍Java虚拟机——JVM的相关内容。 “基础知识”是本专栏的第一个部分&#xff0c;本篇博文是第四篇博文&#xff0c;如有需要&#xff0c;可&#xff1a; 点击这里&#xff0c;返回…...

项目管理-计算专题(三点估算、PERT估算)

基本概念 通过考虑估算中的不确定性和风险&#xff0c;可以提高活动持续时间估算的准确性。这个概念源自计划评审技术(PERT)。PERT使用三种估算值来界定活动持续时间的近似区间: 最可能时间(tM)&#xff1a;基于最可能获得的资源、最可能取得的资源生产率、对资源可用时间的现…...

【华为OD机试 2023最新 】模拟商场优惠打折(C语言题解 100%)

文章目录 题目描述输入描述输出描述用例题目解析代码思路C语言题目描述 模拟商场优惠打折,有三种优惠券可以用,满减券、打折券和无门槛券。 满减券:满100减10,满200减20,满300减30,满400减40,以此类推不限制使用; 打折券:固定折扣92折,且打折之后向下取整,每次购…...

使用TrieTree(字典树)来实现敏感词过滤

使用TrieTree&#xff08;字典树&#xff09;来实现敏感词过滤 1. 字典树定义 字典树&#xff08;TrieTree&#xff09;&#xff0c;是一种树形结构&#xff0c;典型应用是用于统计&#xff0c;排序和保存大量的字符串&#xff08;但不仅限于字符串,如01字典树&#xff09;。…...

USB转串口芯片CH9101U

CH9101是一个USB总线的转接芯片&#xff0c;实现USB转异步串口。提供了常用的MODEM联络信号&#xff0c;用于为计算机扩展异步串口&#xff0c;或者将普通的串口设备或者MCU直接升级到USB总线。 特点 全速USB设备接口&#xff0c;兼容USB V2.0。内置固件&#xff0c;仿真标准串…...

Java语言介绍

Java是一种广泛使用的计算机编程语言&#xff0c;由Sun Microsystems公司于1995年推出。它是一个健壮的、面向对象的、跨平台的语言&#xff0c;被用于开发各种应用程序和系统&#xff0c;包括Web应用程序、移动应用程序、桌面应用程序、游戏以及企业级系统等。 Java具有许多优…...

外海赌博如何做网站的推广/职业教育培训机构排名前十

求助&#xff1a;如何实现不关机SIM卡插拔(不用PUSH式卡座)kenny_nap Post at 2010/12/14 20:27:37有一个平板项目&#xff0c;SIM卡座是侧边&#xff0c;使用频率很高&#xff0c;push式卡座寿命普遍较短&#xff0c;准备使用普通抽屉式卡座&#xff0c;请教各位有什么好的办法…...

蘑菇街网站怎么做/chrome官方下载

print语句 print hello, world print hello, world # , 隔开&#xff0c;输出时&#xff0c;打印一个空格 print 100200 注释语句 #从开头到行尾都是注释赋值语句 创建内存&#xff0c;指向相应的地址 #不等同于数学的等式 x 2 x x 2 条件语句 if语句 if score > 6…...

网站开发的技术栈/软文营销文章范文

基于文件流的读取与写入是Android平台上的数据存取方式之一。 在Android中&#xff0c;可以通过Context.openFileInput和Context.openFileOutput来分别获取FileInputStream和FileOutputStream。 openFileInput(String fileName); 打开应用程序私有目录下的指定私有文件以读…...

服务器可以做自己网站用吗/搜索引擎营销ppt

WhiteBoard白板功能很强大。 可以直接在网页上进行圈画&#xff0c;然后截图。 ImageEditor是一个很好用的画图功能&#xff0c;比windows画图的箭头好看。 转载于:https://www.cnblogs.com/Tpf386/p/8876973.html...

斌果主题wordpress/武汉seo服务多少钱

C# 基础 面向对象泛型委托、Lambda表达式和事件LINQ动态语言异步编程异常反射内存管理 多线程 线程基础线程同步使用线程池使用任务并行库async await使用并发集合使用PLINQ使用异步I/O并行编程模式使用Reactive Extensions 测试 单元测试 测试框架 NUnitxUnitMSTest 模拟…...

flash网站设计实例/亚洲长尾关键词挖掘

mysql均衡负载 一、利用mysql 复制分流查询操作&#xff1a; 利用mysql的主从复制可以有效的分流更新操作和查询操作&#xff0c;具体的实现是一个主服务器&#xff0c;承担更新操作&#xff0c;多台从服务器&#xff0c;承担查询操作&#xff0c;主从之间通过复制实现数据的同…...