文件I/O--C++的文件操作

发布于:2025-03-25 ⋅ 阅读:(24) ⋅ 点赞:(0)

一、打开文件,从文件中读取、写入文件

从文件中读取数据: 

#include<fstream>  //fstream  File stream:文件流 
#include<iostream> //fstream包含了 iostream,所以这句可以省略,现在不能了 

using namespace std;

int main()
{
	ifstream in;                        //ifstream(文件读取类): input file stream :文件输入流
	
	in.open("test.txt");               //打开 "test.txt" 文件(项目所在文件夹!!!) 
	if(!in){                           //如果in为0(!in非0) ,则:显示打开失败 ,对象返回值为0 
		cerr<<"打开文件失败"<<endl;   //endl:输出换行 
			return 0;
	}
	
	char x; //char:1个字节           //在c++中,可以再任何地方定义变量 
	while(in>>x)                     //in>>x 从文件in(test.txt)流入到字符x里面去,一次流入1个字节 
	{
		cout<<x;                    //从x流到cout(输出终端) 
	}                               //直到没有东西流,则退出循环 
	
	cout<<endl;
	in.close();                    //关闭文件 
	
	return 0;
}

1.扩展:cerr、out、clog三种输出方式 

(1)std::cerr(标准错误输出):

  • 用途: 用于输出错误信息或紧急消息,主要在程序遇到错误或异常时使用。它通常用于警告、错误日志、或异常信息的输出。它适合输出紧急信息
  • 缓冲: 不带缓冲(即时输出)。输出的数据不会存储在缓冲区中,而是立即输出到控制台。这对于错误信息来说很重要,因为我们希望错误消息能尽快显示,而不是等待缓冲区被刷新。
  • 场景: 打印错误消息、调试时的异常信息。
std::cerr << "Error: Something went wrong!" << std::endl;

 (2)std::cout(标准输出):

  • 用途: 用于一般的标准输出,通常是将普通的程序输出(如结果、信息)打印到控制台。适用于用户需要查看的正常输出
  • 缓冲: 带缓冲。输出的内容通常会先进入缓冲区,然后在缓冲区满、程序结束、或调用 std::endl/std::flush 时刷新到控制台。这意味着它的性能通常较好,因为减少了频繁的IO操作。
  • 场景: 打印计算结果、程序执行状态、欢迎信息等。
std::cout << "This is a normal output." << std::endl;

 (3)std::clog(标准日志输出):

  • 用途: 用于输出日志信息,适合调试或记录程序执行情况。虽然在现代开发中,专用的日志库(如 spdlog、glog 等)更为常见,但 std::clog 是标准库中提供的日志输出流。
  • 缓冲: 带缓冲。和 std::cout 一样,std::clog 的输出也先进入缓冲区,需要手动或自动刷新。这种行为适用于日志记录,因为日志通常不会要求即时输出,但可以用来保存调试或程序运行的日志信息。
  • 场景: 写调试日志、程序跟踪信息。
std::clog << "This is a log message." << std::endl;

写入数据到文件中: 

#include<fstream>
#include<iostream>

using namespace std;

int main()
{
	ofstream out;              //ofstream:文件写入类 
	
	out.open("test1.txt");     //打开 "test.txt" 文件 
	if(!out){
		cerr<<"打开文件失败"<<endl;
		return 0;
	}
	
	for(int i=0;i<10;i++){
		out<<i;               //把0-9这10数字 从变量i流到了out文件(指向test.txt)里面去 
	}
	
	out<<endl;
	out.close();             //关闭文件 
	
	return 0;
}


(1)ifstream:文件读取类

  • “i”代表“input”(输入),输入文件流,这个类继承自 istream。
  • ifstream 类用于从文件中读取数据,但不能写入或更改文件的内容。
  • 示例用途包括读取配置文件、文本文件等。
  • ifstream是从硬盘到内存(其实所谓的流缓冲就是内存空间)

(2)ofstream:文件写入类

  • 输出文件流,用于 创建文件 并且向文件中 写入数据
  • ofstream是从内存到硬盘(其实所谓的流缓冲就是内存空间)

注意: fstream    文件流,有读写功能,即是以上两个的综合



二、使用构造函数打开文件 

//打开文件方式一:
ifstream in;
in.open("test.txt")


//方式二:
ifstream in("test.txt");//使用构造函数(对象默认使用的方法)
//打开文件方式一:
ofstream out;
out.open("test.txt")


//方式二:
ofstream out("test.txt");//使用构造函数(对象默认使用的方法)


三、文件的常见打开模式

ifstream in(char* filename,int open_mode);

  • filename:文件的名称(字符串)
  • open_mode:文件的打开模式,它的值用来定义以怎样的方式打开文件。
常见文件的打开模式
ios::in 打开一个可读取文件
ios::out 打开一个可写入文件
ios::binary 二进制的形式打开一个文件
ios::app 写入的所有数据将被追加到文件的末尾
ios::trunk 删除文件原来已经存在的内容
ios::nocreate 如果要打开的文件并不存在,那么以此参数调用open函数将无法进行
ios::noreplace 如果要打开的文件并已经存在,试图用open函数打开时将返回一个错误
#include<fstream>
#include<iostream>

using namespace std;

int main()
{
	ofstream out("test.txt",ios::app);//以添加的形式打开 
	
	if(!out)
	{
		cerr<<"文件打开失败!"<<endl;
		return 0; 
	}
	
	for(int i=10;i>0;i--){
	  out<<i;
	}
	
	 out<<endl;
	 out.close();
	 
	 return 0;
}

使用多种打开模式:使用OR操作符  "  |  ":

#include<fstream>
#include<iostream>

using namespace std;

int main()
{
	fstream fp("test1.txt",ios::in | ios::out);//以可读同时可写的形式打开 
	if(!fp)
	{
		cerr<<"文件打开失败!"<<endl;
		return 0; 
	}
	
	fp<<"IloveFish.com";//"把I love Fish.com流入到fp对象里" (写入)
	
	static char str[100];//定义一个静态的数组 (定义一个不能被改变的数组) 
	
	fp.seekg(ios::beg);// ios::beg使得文件指针指向文件头  ios::end得文件指针指向文件尾 
	fp>>str;//把fp的内容流向str数组 
	cout<<str<<endl;//把数组显示到显示终端上 (读取) 
	
	fp.close();//关闭文件 

	 return 0;
}



四、课后作业:编写一个fileCopy.cpp文件,实现文件复制功能。

方式一:

#include <fstream>
#include <cstdlib>
#include <iostream>


using namespace std;


int main(  )
{
		
	char src_file_name[100]; //定义原文件名 
	char dest_file_name[100]; //定义目标文件名 
	
	cout<<"请输入源文件名: "; 
	std::cin>> src_file_name;  //输入 原文件名 
	cout<<"请输入目标文件名: "; 
	std::cin >> dest_file_name; //输入 目标件名 
   
 

	ifstream in(src_file_name);//打开原文件 
	if(!in)
	{
		cerr<<"原文件文件打开失败!"<<endl;
		return 0; 
	}	

	ofstream out(dest_file_name);//打开目标文件	
	if(!out)
	{
		cerr<<"目标文件打开失败!"<<endl;
		return 0; 
	}	
	
	//把文件内容读取出来写入目标文件中 
    char buffer[1024];
//    while(in>>buffer)
//	{
//	    out<<buffer;
//	}

	in>>buffer;
	out<<buffer;
	

    
    in.close();//关闭文件 
    out.close();//关闭文件 

    cout<<"文件复制成功"<<endl;  
	return 0;
}


方式二:

#include <fstream>
#include <cstdlib>
#include <iostream>


using namespace std;

void print_error( const char* a, const char* b=" ");

int main( int argc, char* argv[] )
{
	//argc:argv[]数组的长度 
	//argv[]:内容,
    //for (int i=0;i<argc;i++){cout << argv[i] <<endl;}    
	
	 
//	cout<<argv[0]<<endl;//D:\c++demo\fileCopy1.exe 
   
    if( argc!=3)                      //检查命令行参数个数是否为3: argv[0]=原文件名 argv[1]=原文件  argv[2]=目标文件
    {
        print_error( "输入形式: copyFile 源文件名 目标文件名 \n" );
        return 1;                    //返回非0值表示程序执行失败 
    }
	
	
	ifstream in(argv[1]);           //打开原文件 
	if(!in)
	{
		cerr<<"原文件文件打开失败!"<<endl;
		return 1; 
	}	

	ofstream out(argv[2]);//打开目标文件	
	if(!out)
	{
		cerr<<"目标文件打开失败!"<<endl;
		return 1; 
	}	
	
	//把文件内容读取出来写入目标文件中 
    char buffer[1024];
//    while(in>>buffer) //一个字节一个字节读 
//	{
//	    out<<buffer;
//	}

	in>>buffer;
	out<<buffer;
	

    
    in.close();//关闭文件 
    out.close();//关闭文件 

    cout<<"文件复制成功"<<endl;  
	return 0;
}

void print_error( const char* a, const char* b)//参数为指针类型(字符串内部也是指针) 
{
	cout << a << endl;
}

1.扩展:返回值0 1 -1 

return 0 代表程序正常退出,return 1代表程序异常退出:

  • 在main函数中,返回0表示程序正常结束,没有发生错误。
  • 返回1一般用于表示程序执行过程中出现了某种错误或异常情况,但具体的错误类型并没有明确规定,致使一种约定俗成的表示方法。

未完待续。。。