C++文件基础操作总结
背景
最近正在完成C++的结课作业,设计图书管理系统,所以对文件的相关操作进行复习总结,特出此文。
流对象
C++通过三个类支持文件的输入输出
-
ofstream :写操作(输出)
-
ifstream :读操作(输入)
-
fstream :同时可以读写操作
打开文件夹
将以上类的一个对象与文件联系起来,自此对对象的操作就是对文件的操作。
操作函数:open(const char* filename, openmode mode);
参数:filename是文件的路径。 openmode包括一下图片中的模式
我们可以用或(|)将多种模式组合起来。
比如:
#include<iostream>
#include<fstream>
using namespace std;
int main()
{
fstream file;
file.open("text.txt", ios::in|ios::out);
// fstream file("text.txt",ios::in|ios::out);也是允许的。
if(file.is_open())
{
cout << "file opening is successful." << endl;
}
file.close();
return 0;
}
检查文件是否打开成功——is_open()
使用方法:流对象. is_open()
,若成功返回(true).
关闭文件
流对象.close()
文本文件
因为ofstream,ifstream,fstream是由ostream,istream,iostream继承而来,所以也可使用<<和>>来读写文件
写入数据
流对象<<"………";
#include<iostream>
#include<fstream>
using namespace std;
int main()
{
fstream file("text.txt",ios::in|ios::out);
if(file.is_open())
{
file<<"I love you!\n";
file.close();
}
return 0;
}
读数据
判断是否到文件尾:流对象.eof()
读入信息:流对象.getline(char* buffer,int char_number,[char end_char]);
buffer是用来存储文件信息的字符数组,char_number是读取字符的最大个数,最后是一个可选参数(可以这么理解,实际上是重载函数),代表遇到什么字符是停止读取
如:
在D:\vs2019\cpp\text路径下,我新建一个文本文档TextFile1.txt
文件内容为我随意输入的东西
biabscajbdcjskdv svs
bcjsc jhs
#include <iostream>
#include <fstream>
#include <cstdlib>
using namespace std;
int main()
{
char buffer[256];
ifstream examplefile("D:\\vs2019cpp\\text\\TextFile1.txt");
if (!examplefile.is_open())
{
cout << "Error opening file"; exit(1);
}
while (!examplefile.eof())
{
examplefile.getline(buffer, 21);
cout << buffer << endl;
}
return 0;
}
获得和设置流指针
ifstream 有一个指针,指向下一个被读取的元素(get pointer)
ofstream有一个指针,指向写入下一个元素的位置(put pointer)
fstream通知继承了上面两种。
通过以下成员函数读出或配置流指针:
tellg() and tellp()
不用传参数,返回一个整数代表当前get流指针(tellg)或put 流指针的位置(tellp)
seekg() and seekp()
改变流指针的位置。
有两种用法:
seekg(pos_type position);
seekp(pos_type position);
改变从文件开始计算的一个绝对位置。
seekg(off_type offset,seekdir direction);
seekkp(off_type offset,seekdir direction);
指定由一个具体的指针开始计算位移(offset).
direction 可以是:
-
ios::beg(begin)文件头
-
ios::cur(current)当前位置
-
ios::end. 文件尾
如:
#include <iostream> #include <fstream> using namespace std; int main() { const char* filename = "D:\\vs2019cpp\\text\\TextFile1.txt"; long m; ifstream file(filename, ios::in | ios::binary); file.seekg(0, ios::end); m = file.tellg(); file.close(); cout << "size of " << filename; cout << " is " << m << " bytes.\n"; return 0; }
size of D:\vs2019cpp\text\TextFile1.txt is 31 bytes.
注意:对于文本文件建议总是以seekg和seekp的第一个原型。
二进制文件任意使用
二进制文件
在二进制文件中使用<<,>>,以及函数来操作输入和输出数据(比如getline)没有实际意义。
文件流包括两个为__顺序读写__数据特殊设计的成员函数:
原型:
write (unsigned char * buffer, streamsize size );(ofstream)
read ( char * buffer, streamsize size );(ifstream)
#include <iostream>
#include <fstream>
using namespace std;
int main ()
{
const char * filename = "TextFile1.txt";
char * buffer;
long size;
ifstream file(filename, ios::in|ios::binary|ios::ate);//打开二进制文件,并将指针指向末尾
size = file.tellg();//通过tellg函数获得文件的大小
file.seekg(0, ios::beg);//将文件指针指向文件头
buffer = new char [size];//申请size大小的空间进行存储文件信息
file.read(buffer, size);//开始读入文件信息
file.close();//关闭文件
cout <<"the complete file is in a buffer";
delete[] buffer;//释放申请的空间
return 0;
}
二进制读写的其他函数
-
put()
put()函数向流写入一个字符,其原型是ofstream &put(char ch)。
使用也比较简单,如file1.put(‘c’);就是向流写一个字符’c’。
-
get()
get()函数比较灵活,有3种常用的重载形式:
-
一种就是和put()对应的形式:ifstream &get(char &ch);功能是从流中读取一个字符,结果保存在引用ch中,如果到文件尾,返回空字符。如file2.get(x);表示从文件中读取一个字符,并把读取的字符保存在x中。
-
另一种重载形式的原型是: int get();这种形式是从流中返回一个字符,如果到达文件尾,返回EOF,如x=file2.get();和上例功能是一样的。
-
还 有一种形式的原型是:ifstream &get(char *buf,int num,char delim=‘n’);
这种形式把字符读入由 buf 指向的数组,直到读入了 num 个字符或遇到了由 delim 指定的字符,如果没使用 delim 这个参数,将使用缺省值换行符’n’。例如:
如:
-
另一种重载形式的原型是: int get();这种形式是从流中返回一个字符,如果到达文件尾,返回EOF,如x=file2.get();和上例功能是一样的。
-
还 有一种形式的原型是:ifstream &get(char *buf,int num,char delim=‘n’);
这种形式把字符读入由 buf 指向的数组,直到读入了 num 个字符或遇到了由 delim 指定的字符,如果没使用 delim 这个参数,将使用缺省值换行符’n’。例如:
如:
file2.get(str1,127,'A');//从文件中读取字符到字符串str1,当遇到字符'A'或读取了127个字符时终止。
分割字符串
<string.h>
函数声明:
char *strtok( char *strToken, const char *strDelimit );
选自MSDN:
#include <string.h>
#include <stdio.h>
char string[] = "A string\tof ,,tokens\nand some more tokens";
char seps[] = " ,\t\n";
char* token;
int main(void)
{
printf("Tokens:\n"); // Establish string and get the first token:
token = strtok(string, seps); // C4996
// Note: strtok is deprecated; consider using strtok_s instead
while (token != NULL)
{ // While there are tokens in "string"
printf(" %s\n", token); // Get next token:
token = strtok(NULL, seps); // C4996
}
}