C语言版本的文件io

1.打开文件,确定权限

1
2
3
4
5
FILE * fp = fopen("filename","rw")
/*fopen("文件路径","权限")有返回值,返回0时表示关闭文件失败
*文件路径:绝对路径或者相对路径
*权限w(写),r(读),a(追加),r+,w+,a+(+号表示文件必须存在才能进行操 作,没有加号时文件不存在会自动创建)
*/

2.获取文件流,写入文件句柄

1
2
3
4
5
6
7
8
char buffer[] = "hello wolrd";
fwrite(buffer,sizeof(char),sizeof(buffer),fp);
/***
有返回值,返回0时表示关闭文件失败
*buffer指的是要写入文件的数据流
*sizeof(char)表示要写入的数据流类型为char类型
*sizeof(buffer)表示要写入的文件长度为一个buffer长度
*fp表示要操作的文件句柄

3.读取文件内容

1
2
3
4
5
6
7
8
char Buf[12];//数组要提前确定长度
fread(Buf,sizeof(char),sizeof(buffer),fp);
/****
*Buf表示文件要流入的容器
*sizeof(char)数据类型长度
*sizeof(buffer)要流出的长度
*fp所操作的文件句柄
****/

4.关闭文件

1
fclose(fp);//fp为文件句柄,有返回值,返回0时表示关闭文件失败

5.完整C代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include "stdio.h"
void openfile() {
FILE* fp = fopen("test.txt", "rw");
if (fp == 0) printf("open file final");
char buffer[] = "hellowolrd";
char Buf[12];
fwrite(buffer, sizeof(char), sizeof(buffer), fp);
fread(Buf, sizeof(char), sizeof(buffer), fp);
for (int i = 0; i < sizeof(Buf); i++) printf("%c", Buf[i]);
fclose(fp);
}

int main(void) {
openfile();
return 0;
}

C++版本的文件io

1.直接使用流对象进行文件的操作,默认方式如下:

1
2
3
4
ofstream out("...", ios::out);
ifstream in("...", ios::in);
fstream foi("...", ios::in|ios::out);
123

文件写操作

1
2
3
4
5
6
7
8
9
10
11
12
13
 // writing on a text file
#include <fiostream.h>
int main () {
ofstream out("out.txt");
if (out.is_open())
{
out << "This is a line.\n";
out << "This is another line.\n";
out.close();
}
return 0;
}
123456789101112

文件读操作

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
 // reading a text file
#include <iostream.h>
#include <fstream.h>
#include <stdlib.h>
int main () {
char buffer[256];
ifstream in("test.txt");
if (! in.is_open())
{ cout << "Error opening file"; exit (1); }
while (!in.eof() )
{
in.getline (buffer,100);
cout << buffer << endl;
}
return 0;
}
12345678910111213141516

2.open函数

1
2
3
4
5
6
7
void open ( const char * filename,  
ios_base::openmode mode = ios_base::in | ios_base::out );

void open(const wchar_t *_Filename,
ios_base::openmode mode= ios_base::in | ios_base::out,
int prot = ios_base::_Openprot);
123456

参数:

filename 操作文件名

mode 打开文件的方式

prot 打开文件的属性 //基本很少用到,在查看资料时,发现有两种方式

**打开文件的方式(mode ): **

1
2
3
4
5
6
7
8
9
ios::app:    //以追加的方式打开文件  
ios::ate:    //文件打开后定位到文件尾,ios:app就包含有此属性
ios::binary:  //以二进制方式打开文件,缺省的方式是文本方式。两种方式的区别见前文
ios::in:    //文件以输入方式打开(文件数据输入到内存)
ios::out:    //文件以输出方式打开(内存数据输出到文件)
ios::nocreate: //不建立文件,所以文件不存在时打开失败
ios::noreplace://不覆盖文件,所以打开文件时如果文件存在失败
ios::trunc:  //如果文件存在,把文件长度设为0
12345678

打开文件的属性取值(prot ):

1
2
3
4
5
6
0:普通文件,打开访问  
1:只读文件
2:隐含文件
4:系统文件
可以用“或”或者“+”把以上属性连接起来,如3或1|2就是以只读和隐含属性打开文件
12345

状态标志符:

除了eof()以外,还有一些验证流的状态的成员函数(所有都返回bool型返回值):

1
2
3
4
5
6
is_open():文件是否正常打开
bad():读写过程中是否出错(操作对象没有打开,写入的设备没有空间)
fail():读写过程中是否出错(操作对象没有打开,写入的设备没有空间,格式错误--比如读入类型不匹配)
eof():读文件到达文件末尾,返回true
good():以上任何一个返回true,这个就返回false
12345

要想重置以上成员函数所检查的状态标志,你可以使用成员函数clear(),没有参数

获得和设置流指针

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
- 对于所有的输入输出流都有至少一个指针,指向下一个要操作的位置

ofstream put_point

ifstream get_point

fstream put_point和get_point

- 获取流指针位置

tellg(): 返回输入流指针的位置(返回类型long)

tellp(): 返回输出流指针的位置(返回类型long)

- 设置指针位置

seekg(long position): 设置输入流指针位置为第position个字符(文件首位置为开始位置)

seekp(long position): 设置输出流指针到指定位置
12345678910111213141516171819
// position in output stream
#include <fstream> // std::ofstream

int main () {

std::ofstream outfile;
outfile.open ("test.txt");

outfile.write ("This is an apple",16);
long pos = outfile.tellp();
outfile.seekp (pos-7);
outfile.write (" sam",4);

outfile.close();

return 0;
}
1234567891011121314151617

seekg ( off_type offset, seekdir direction );
seekp ( off_type offset, seekdir direction );
使用这个原型可以指定由参数direction决定的一个具体的指针开始计算的一个位移(offset)。它可以是:

ios::beg 从流开始位置计算的位移
ios::cur 从流指针当前位置开始计算的位移
ios::end 从流末尾处开始计算的位移

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
//假设test.txt中的内容是HelloWorld
ifstream fin("test.txt",ios::in);
cout << fin.tellg();//输出0,流置针指向文本中的第一个字符,类似于数组的下标0

char c;
fin >> c;
fin.tellg();//输出为1,因为上面把fin的第一个字符赋值给了c,同时指针就会向后 移动一个字节(注意是以一个字节为单位移动)指向第二个字符

fin.seekg(0,ios::end);//输出10,注意最后一个字符d的下标是9,而ios::end指向的是最后一个字符的下一个位置

fin.seekg(10,ios::beg);//和上面一样,也到达了尾后的位置

//我们发现利用这个可以算出文件的大小

int m,n;
m = fin.seekg(0,ios::beg);
n = fin.seekg(0,ios::end);
//那么n-m就是文件的所占的字节数

我们也可以从文件末尾出发,反向移动流指针,
fin.seekg(-10,ios::end);//回到了第一个字符
123456789101112131415161718192021

读取文件内容:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
// print the content of a text file.
#include <iostream> // std::cout
#include <fstream> // std::ifstream

int main () {
std::ifstream ifs;

ifs.open ("test.txt", std::ifstream::in);

char c = ifs.get();

while (ifs.good()) {
std::cout << c;
c = ifs.get();
}

ifs.close();

return 0;
}
1234567891011121314151617181920

使用重载的’<<’ 或者 ‘>>’, 也可以使用成员函数来实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include <fstream>
using namespace std;

int main ()
{
ifstream fr;
ofstream fw;
char word[200], line[200];

fw.open("write.txt");
fr.open("read.txt");

fr >> word; //读取文件,一个单词
fr.getline (line, 100); //读取一行内容

fw << "write file test" << endl;

fw.close();
fr.close();

return 0;
}

cout/cin重定向

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
void Rediect() {
string name;
cin >> name;
freopen("file.txt", "w", stdout);
cout << name << "\n";
freopen("file.txt", "r", stdin);//重定向到文件
cin >> name;
cerr << name << "\n";
freopen("/dev/tty", "w", stdout); //重定向到控制台
//Windows平台是freopen("CON", "r", stdin);
}

int main(void) {
Rediect();
cout << "hello wolrd \n" << endl;
return 0;
}