学习资源汇总来源于中国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子文件夹里面
文件的读写指针
- 对于输入文件,有一个读指针;
- 对于输出文件,有一个写指针;
- 对于输入输出文件,有一个读写指针;
- 标识文件操作的当前位置, 该指针在哪里,读写操 作就在哪里进行。
显示关闭文件·
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’