目录
今天写数据结构的时候涉及到了文件的操作,因为已经碰到好多次了而我总是对这部分不太熟悉,于是索性就来写个简单的应用总结吧。
还有更多的细节就不在这里深究了,感兴趣的小伙伴可以自己去查阅资料哈。
第一次写这么长的博客hhh,有不同意见也可以在评论区中发表。多多鼓励哈。
今天写数据结构的时候涉及到了文件的操作,因为已经碰到好多次了而我总是对这部分不太熟悉,于是索性就来写个简单的应用总结吧。
c++中对文件的操作基本通过stream的子类fstream(file stream)来实现的,需要加入头文件fstream.h
一、打开文件
成员函数open(),
原型 :void open(const char* filename, int mode, int access);
参数:filename:要打开的文件名,mode打开文件的方式,access打开文件的属性
mode在类ios(所有流式I/O类基类)中定义,常用值:(可使用|连接)
ios::app:以追加方式打开文件
ios::ate:打开后定义到文件尾,app就包含此属性
ios::binary:二进制方式打开
ios::in:输入方式
ios::out:输出方式
ios::nocreate:无文件时打开失败
ios::noreplace:文件存在时打开失败
ios::trunc:如果文件存在把文件长度设为0
access:(可使用|或+连接)
0普通文件,打开访问
1只读文件
2隐含文件
4系统文件
使用:
打开文件Code.txt
1.
fstream file1;
file1.open("Code.txt", ios::in|ios::out, 0);
2.省略后两个参数默认以读写普通文件打开
fstream file1;
file1.open("Code.txt");
3.定义的时候打开
fstream file1("Code.txt")
4.使用fstream的子类ifstream或ofstream默认以输入或输出方式打开
ifstream file2("Code.txt");
ofstream file3("Code.txt");
二、关闭文件
成员函数close();
file1.close();
三、读写文件(文本文件和二进制文件)
1、文本文件:
(1)使用插入器<<和析取器>>读写:
file2<<"I love you"; //向文件写入字符串 "I love you"
int i;
file1>>i; //从文件输入一个整数值。
控制格式(格式化):
dec 格式化为十进制数值
endl 输出一个换行符并刷新此流
ends输出一个空字符
hex 格式化为十六进制
oct 格式化为八进制
setprecision()设置精度
使用:
file1<<hex<<123; //输出123的十六进制
file1<<setprecision(5)<<3.1415926 //输出5位有效数字
ps:
setprecision(5)是输出5位有效数字,而fixed<<setprecision(5)是输出小数点后5位。
(2)getline()函数
头文件:<fstream>
1)逐行读取, 将行读入字符串, 行之间用回车换行区分:
ifstream file1("Code.txt");
getline(file1, str);
2) 逐词读取, 词之间用空格区分
file1>> str
3)逐行读取, 将行读入字符数组, 行之间用回车换行区分:
file1.getline(str, 125);
2、二进制文件:
1.put()函数
原型:ofstream &put(char ch)
使用:
file1.put('c'); //向流写一个字符'c'
2.get()函数
原型:
1)ifstream &get(char &ch) //从流中保存一个字符,结果保存在引用ch中如果到文件尾,返回空字符
使用:
file2.get(x);
2)int get();
使用:
x=file2.get();
3)ifstream &get(char *buf, int num, char delim='n');
//把字符读入由buf指向的数组,直到读入了num个字符或遇到了由delim指定的字符(默认为换行符'n')
使用:
file2.get(str1, 127, 'A');
3、读写数据块
read()和write()成员函数
原型:
read(unsigned char *buf, int num);
write(const unsigned char *buf, int num);
//read()从文件中读取num个字符到buf指向的缓存中如果还未读入num就到了文件尾,可使用int gcount()函数来取得实际读取的字符数。
//write()从buf指向的缓存写num个字符到文件中,注意缓存的类型是unsigned char *
使用:
unsigned char str1[]="I love you";
int n[5];
ifstream in("xxx.xxx");
ofstream out("yyy.yyy");
out.write(str1, strlen(str1)); //把字符串str1全部写到yyy.yyy中
in.read((unsigned char*)n, sizeof(n)); //从xxx.xxx中读取指定个整数
in.close();
out.close();
四、检测EOF
eof()函数检测是否到达文件尾,是返回非0值不是返回0.
原型:int eof();
使用:
if(in.eof()ShowMessage("已经到达文件尾!");
ps:这里有个坑,因为eof()函数有一个初始值 上程序的判断顺序会导致最后被读两遍,所以需要在读取的后面加一个判断如果eof的值为ture了则停止读取。
五、文件定位
c++I/O系统管理两个与一个文件相联系的指针。一个是读指针,它说明输入操作在文件中的位置;另一个是写指针,它说明下次写操作的位置。
每次执行输入或输出时,相应的指针自动变化。所以c++的文件定位分为读位置和写位置定位
对应的函数seekg()//读位置和seekp()//写位置.
原型:
istream &seekg(streamoff offset, seek_dir origin);
ostream &seekp(streamoff offset, seek_dir origin);
streamoff定义于iostream.h中,定义有偏移量offset所能取得的最大值
seek_dir表示移动的基准位置,有以下值:
ios::beg 文件开头
ios::cur 文件当前位置
ios::end 文件结尾
ps:
虽然也可以用于文本文件但会因为系统对字符的解释而与预想值不同
使用:
file1.seekg(1234, ios::cur); //把文件的读指针从当前位置向后移1234个字节
file2.seekp(1234, ios::beg); //把文件的写指针从文件开头向后移1234个字节