常用函数/参数
构造函数
在文件ifstream/ofstream/fstream的构造函数里有两个属性:
ifstream(const char* filename,int mode);
ofstream(const char* filename,int mode)
fstream(const char* filename,int mode)
其中ofstream只用来输出,infream只用了输入,fstream输入输出均可。
filename
即文件的路径,这里\要改成\\。
mode
mode | 作用 |
---|---|
ios::app | 以追加的方式打开文件 |
ios::ate | 文件打开后定位到文件尾,ios:app就包含有此属性 |
ios::binary | 以二进制方式打开文件 |
ios::in | 文件以输入方式打开(文件数据输入到内存) |
ios::out | 文件以输出方式打开(内存数据输出到文件) |
ios::nocreate | 不建立文件,所以文件不存在时打开失败 |
ios::noreplace | 不覆盖文件,所以打开文件时如果文件存在失败 |
ios::trunc | 如果文件存在,把文件长度设为0 |
判断文件是否打开成功
int main()
{
ifstream in("hahadsf");
if( !in )
{
cout << "No!!!" << endl;
return 0;
}
}
seekg()
seekg()有两种形式
seekg(pos_type);
seekg(off_type, ios::seek_dir)
第一种形式就是移动到距离开头pos_type字节的位置。
第二种形式是偏移量,和位置。
关于位置:
ios::seek_dir | 含义 |
---|---|
ios::beg | 输入流开始的位置 |
ios::end | 输入流结束的位置 |
ios::cur | 输入流的当前位置 |
偏移量则是在位置的基础上,向前或向后多少字节。
ifstream in('data.txt');
in.seekg(-5, ios::end);
该语句是定位到从输入流结尾往前数五个字节的位置。
seekp()
该函数是针对输出流的函数,操作方式和seekg()基本一致。
tellp() tellg()
返回输入输出流距离开头多少字节。
常常与seekp()和seekg()结合来获得输入输出流的大小。
ifstream in("data.dat", ios::binary);
in.seekg( 0, ios::end );
int size = in.tellg();
in.seekg( 0, ios::beg );
在找到文件末尾的之后,要把指针移到开头,这样才不会影响后续的读写操作。
文本读写
为了方便,没有给出鲁棒性较高的代码。如并没有判断文件是否打开成功等,文件读写完成也并未关闭。
输出
#include <fstream>
#include <iostream>
using namespace std;
int main()
{
ofstream out("data.txt", ios::out);
string s[] = {"hello", "world", "hi", "Human"};
for (auto str: s) out << str << " ";
out << endl;
int a[] = {1,2,3};
for( auto i: a ) out << i << " ";
}
即所有数据最后都会输出成字符串,用法和cout类似,可以自己根据需要决定输出的形式。
读入
#include <fstream>
#include <iostream>
using namespace std;
int main()
{
ifstream in("data.txt", ios::out);
string s;
while(getline(in, s)) cout << s << endl;
}
即可以比做cin来进行处理,值得注意的一点是如果想要每个字符或者每个字符串读入,要使用下面的写法。
#include <fstream>
#include <iostream>
using namespace std;
int main()
{
ifstream in("data.txt", ios::out);
while(!in.eof())
{
string s; in >> s;
//char c; in >> c;
cout << s << endl;
//cout << c << endl;
}
}
二进制读写
输出
#include <fstream>
#include <iostream>
using namespace std;
struct A
{
double a;
int b;
char c;
void print()
{
cout << "a = " << a << endl;
cout << "b = " << b << endl;
cout << "c = " << c << endl;
}
};
int main()
{
ofstream out("data.dat", ios::binary);
A a[] = { {1,2,'a'},{4,5,'b'} };
out.write( (char* ) a, sizeof(a) );
}
读入
#include <fstream>
#include <iostream>
using namespace std;
struct A
{
double a;
int b;
char c;
void print()
{
cout << "a = " << a << endl;
cout << "b = " << b << endl;
cout << "c = " << c << endl;
}
};
int main()
{
ifstream in("data.dat", ios::binary);
in.seekg( 0, ios::end );
int size = in.tellg();
in.seekg( 0, ios::beg );
A a[size / sizeof(A)];
in.read( (char* )a, size );
for( auto &i : a ) i.print();
}
Output:
a = 1
b = 2
c = a
a = 4
b = 5
c = b
即在输入输出的时候把地址强制转换成char*型的即可。
ps: 需要注意的一点是,有的编译器实现的时候read()函数第二个参数默认是ios::in,这样有可能会造成读取的字节数不够。另外不要对二进制数据使用>>,有的时候会造成错误。