c++ -- 文件操作

学习资源汇总来源于中国MOOC,北大课程


文件创建

#include < fstream > // 包含头文件
ofstream outFile(“clients.dat”, ios::out|ios::binary); //创建文件

– clients.dat” 要创建的文件的名字
– ios::out文件打开方式

	• ios:out 输出到文件, 删除原有内容 
	• ios::app 输出到文件, 保留原有内容,总是在尾部添加 

– ios::binary 以二进制文件格式打开文件

也可以先创建ofstream对象,再用 open函数打开
一般形式

void open(const char* szFileName, int mode)

其中第一个参数是指向文件名的指针,第二个参数是文件的打开模式标记。
示例:

ofstream fout; 
fout.open("test.out",ios::out|ios::binary);

附文件打开模式,下列总结摘自c语言中文网

模式标记 适用对象 作用
ios::in ifstream fstream 打开文件用于读取数据。如果文件不存在,则打开出错。
ios::out ofstream fstream 打开文件用于写入数据。如果文件不存在,则新建该文件;如 果文件原来就存在,则打开时清除原来的内容。
ios::app ofstream fstream 打开文件,用于在其尾部添加数据。如果文件不存在,则新建该文件。
ios::ate ifstream 打开一个已有的文件,并将文件读指针指向文件末尾(读写指 的概念后面解释)。如果文件不存在,则打开出错。
ios:: trunc ofstream 单独使用时与 ios:: out 相同。
ios::binary ifstream ofstream fstream 以二进制方式打开文件。若不指定此模式,则以文本模式打开。
ios::in ios::out fstream 打开已存在的文件,既可读取其内容,也可向其写入数据。文件刚打开时,原有内容保持不变。如果文件不存在,则打开出错
ios::in ios::out ofstream 打开已存在的文件,可以向其写入数据。文件刚打开时,原有内容保持不变。如果文件不存在,则打开出错。
ios::in ios::out ios::trunc fstream 打开文件,既可读取其内容,也可向其写入数据。如果文件本来就存在,则打开时清除原来的内容;如果文件不存在,则新建该文件。

其中istream,ostream与fstream的关系图下所示:
在这里插入图片描述
iostream//输入输出流

istream//输入流

ostream//输出流

除了open打开之外,还可以使用流类的构造函数打开文件,一般形式是:

ofstream::ofstream(char *FileName,int mode = ios::out,int);

第一个参数是文件名指针,第二个是文件打开模式,第三个不常用,为打开文件的属性取值,是整形数据:
0:普通文件,打开访问
1:只读文件
2:隐含文件
4:系统文件

示例:


判断文件打开是否成功,可以看“对象名”这个表达式的值是否为 true,如果为 true,则表示文件打开成功。
判断打开是否成功运用:

 if!fout){ cout << “File open error!<<endl;}

示例:

#include<iostream>
#include <fstream>
#include <cstdlib>
using namespace std;
int cmp( const void* x,const void *y)
{
	return *((int *)x) - *((int *)y);	
} 
int main()
{
	ifstream File("in.txt",ios::in);
	if(!File)
		cout<<"打开失败"<< endl;
	ofstream destFile("out.txt",ios::out);
	if(!destFile)
		cout<<"打开失败"<< endl;
 	int x,num[100],total = 0;
 	while(File >> x)
 		num[total++] = x;
	qsort(num,total,sizeof(int),cmp);
	for(int i = 0;i < total;i++)
		destFile << num[i]<<" ";
	File.close();
	destFile.close();
	return 0;
}
 

其中文件的绝对路径与相对路径
绝对路径:

C:\\Users\\1\\Documents\\1.txt

相对路径

Users\\1\\Documents\\1.txt
	当前盘符的根目录下的Users\\1\\Documents\\1.txt
Users\\1\\Documents\\1.txt
	当前文件夹的User子文件夹里面
..\\Users\\1\\Documents\\1.txt
	当前文件夹的读文件夹下面的User子文件夹里面

文件的读写指针

  1. 对于输入文件,有一个读指针;
  2. 对于输出文件,有一个写指针;
  3. 对于输入输出文件,有一个读写指针;
  4. 标识文件操作的当前位置, 该指针在哪里,读写操 作就在哪里进行。
    在这里插入图片描述
    在这里插入图片描述
    显示关闭文件·
ifstream fin(“test.dat”,ios::in); 
fin.close();

ofstream fout(“test.dat”,ios::out); 
fout.close();

二进制文件读写

ofstream 和 fstream的成员函数:
istream& write (const char* s, long n);
将内存地址s处的n个字节内容,写入到文件中写指针指向的位置, 然后将文件写指针向后移动n字节(以ios::out方式打开文件时,文 件写指针开始指向文件开头, 以ios::app方式打开文件时,文件写指针开始指向文件尾部 ) 。

示例1:

#include <iostream> 
#include <fstream> 
using namespace std;
int main() 
{ 
	ofstream fout("some.dat", ios::out | ios::binary); 
	int x = 120; 
	fout.write( (const char *)(&x), sizeof(int) );//写入文件,注意内存地址 
	fout.close(); 
	ifstream fin("some.dat",ios::in | ios::binary); 
	int y; 
	fin.read((char * ) & y,sizeof(int)); //从文件中读出 
	fin.close(); 
	cout << y <<endl; 
	return 0;
}

示例2:

#include <iostream> 
#include <fstream> 
using namespace std; 
struct Student { 
	char name[20]; 
	int score;
}; 
int main() 
{ 
	Student s; 
	ofstream OutFile( "new.dat",ios::out|ios::binary); //以二进制形式打开 
	while( cin >> s.name >> s.score ) 
	OutFile.write( (char * ) & s, sizeof( s) );
	OutFile.close(); 
	return 0;
}

执行效果
在这里插入图片描述

但是如何转化成控制台输出呢?
和第一个程序一样,借助read即可。

#include <iostream> 
#include <fstream> 
using namespace std; 
struct Student { 
	char name[20]; 
	int score;
}; 
int main()
{
	Student s;
	ifstream inFile("new.dat",ios::in | ios::binary ); 
	if(!inFile) { //不成功 
		cout << "error" <<endl; 
		return 0;
	}
	while( inFile.read( (char* ) & s, sizeof(s) ) ) { 
		int readedBytes = inFile.gcount(); //看刚才读了多少字节 
		cout <<"readedBytes = "<<readedBytes<<" "<< s.name << " " << s.score << endl;
	}
	inFile.close(); 
	return 0;
}

执行效果
在这里插入图片描述
那么进一步修改二进制文件内容呢
在这里插入图片描述
借助指针就可。
iofile.seekp( sizeof(s),ios::beg);按照存储大小,计算位置,此处指向的是第二个元素结构体的位置,ios::beg从开头计算。
iofile.write("mnq",strlen("mnq")+1);写入字符。

文件拷贝程序mycopy 示例

用法示例: mycopy src.dat dest.dat 即将 src.dat 拷贝到 dest.dat 如果 dest.dat 原来就有,则原来的文件会被覆盖 。

#include <iostream> 
#include <fstream> 
using namespace std; 
int main(int argc, char * argv[]) 
{
	ifstream in(argv[1],ios::binary|ios::in); //打开文件用 读 
	if( !in ) 
	{ 
		cout << "Source file open error." << endl; 
		return 0;
	}
	ofstream out(argv[2],ios::binary|ios::out); //打开文件用于写 
	if( !out) 
	{ 
		cout << "New file open error." << endl; 
		out.close(); //打开的文件一定要关闭 return 0;
	}
	char c; 
	while( in.get(c)) //每次读取一个字符 
		out.put(c); //每次写入一个字符
	out.close(); 
	in.close(); 
	cout<<"sucess!"<<endl;
	return 0;
}

执行效果
在这里插入图片描述


二进制文件和文本文件的区别

  • Linux,Unix下的换行符号:‘\n’ (ASCII码: 0x0a)
  • Windows 下的换行符号:‘\r\n’ (ASCII码: 0x0d0a) endl 就是 ‘\n’
  • Mac OS下的换行符号: ‘\r’ (ASCII码:0x0d)
  • Unix/Linux下打开文件,用不用 ios::binary 没区别
  • Windows下打开文件,如果不用 ios::binary,则:
    读取文件时,所有的 ‘\r\n’会被当做一个字符’\n’处理,即少读了一个字 符’\r’。
    写入文件时,写入单独的’\n’时,系统自动在前面加一个’\r’,即多写了一 个’\r’
发布了166 篇原创文章 · 获赞 45 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/qq_44116998/article/details/104258883