1.打开文件

1.1 fstream类型

1

2

3

4

#include <fstream> 

ofstream         //文件写操作 内存写入存储设备  

ifstream         //文件读操作,存储设备读区到内存中 

fstream          //读写操作,对打开的文件可进行读写操作

1.2 open()的函数原型

1

2

3

4

5

6

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);

参数 含义
filename 操作文件名
mode 打开文件的方式
prot 打开文件的属性

1.3 打开方式

打开文件的方式在ios类(所以流式I/O的基类)中定义,有如下几种常用方式:

参数 含义
ios::in 为输入(读)而打开文件
ios::out 为输出(写)而打开文件
ios::ate 初始位置:文件尾
ios::app 所有输出附加在文件末尾
ios::trunc 如果文件已存在则先删除该文件再重新创建
ios::binary 二进制方式

1.4 打开文件的属性

打开文件的属性同样在ios类中也有定义

参数 含义
0 普通文件,打开操作
1 只读文件
2 隐含文件
4 系统文件

1.5 示例代码

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

#include <iostream>

#include <fstream>

#include <iomanip>

using namespace std;

  

int main()

{

    ofstream inFile;

    /*ios::trunc表示在打开文件前将文件清空,由于是写入,文件不存在则创建*/

    inFile.open("inFile.txt",ios::trunc);

  

    int i;

    char a='a';

    for(i=1;i<=26;i++)//将26个数字及英文字母写入文件

    {

        inFile<<setw(2)<<i<<"\t"<<a<<"\n";

        a++;

    }

    inFile.close();//关闭文件

}

2.文本文件的读写

2.1 写文件示例

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

// writing on a text file 

 #include <fstream.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; 

 

//结果: 在out.txt中写入: 

This is a line. 

This is another line

2.2 读文件示例

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

// 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() )  //eof到文件末尾返回true

       

           in.getline (buffer,100); 

           cout << buffer << endl; 

       

       return 0; 

   

   //结果 在屏幕上输出 

    This is a line. 

    This is another line

2.3 逐字符读取和逐行读取

首先说说getline函数,需要头文件#include<string>

函数原型:istream& getline ( istream &is , string &str , char delim );

其中,istream &is 表示一个输入流,譬如cin;

string&str表示把从输入流读入的字符串存放在这个字符串中(可以自己随便命名,str什么的都可以);

char delim表示遇到这个字符停止读入,在不设置的情况下系统默认该字符为'\n',也就是回车换行符

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

#include <iostream>

#include <fstream>

using namespace std;

void testByChar()

{

    fstream testByCharFile;

    char c;

    testByCharFile.open("inFile.txt",ios::in);

    while(!testByCharFile.eof())

    {

        testByCharFile>>c;

        cout<<c;

    }

    testByCharFile.close();

}

void testByLine()

{

    char buffer[256];

    fstream outFile;

    outFile.open("inFile.txt",ios::in);

    cout<<"inFile.txt"<<"--- all file is as follows:---"<<endl;

    while(!outFile.eof())

    {

        outFile.getline(buffer,256,'\n');//getline(char *,int,char) 表现该行字符达到256个或碰到换行就结束

        cout<<buffer<<endl;

    }

    outFile.close();

}

int main()

{

   cout<<endl<<"逐个字符的读取文件:testByChar() "<<endl<<endl;

   testByChar();

   cout<<endl<<"将文件每行内容存储到字符串中,再输出字符串 :testByLine()"<<endl<<endl;

   testByLine();

}

2.4 统计文本行数及读取某一行内容

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

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

//如何统计文本的行数及如何读取文件某一行内容:

  

#include <iostream>

#include <fstream>

#include <string>

using namespace std;

  

int CountLines(char *filename)

{

    ifstream in;

    int n=0;

    string tmp;

    in.open(filename,ios::in);//ios::in 表示以只读的方式读取文件

    if(in.fail())//文件打开失败:返回0

    {

        return 0;

    }

    else//文件存在

    {

        while(getline(in,tmp,'\n'))

        {

            n++;

        }

        in.close();

        return n;

    }

}

  

string ReadLine(char *filename,int line)

{

    int lines,i=0;

    string temp;

    fstream file;

    file.open(filename,ios::in);

    lines=CountLines(filename);

  

    if(line<=0)

        return "Error 1: 行数错误,不能为0或负数。";

    if(file.fail())

        return "Error 2: 文件不存在。";

    if(line>lines)

        return "Error 3: 行数超出文件长度。";

     

    while(getline(file,temp)&&i<line-1)

    {

        i++;

    }

    file.close();

    return temp;

}

int main()

{

    int line;

    char filename[]="inFile.txt";

    cout<<"该文件行数为:"<<CountLines(filename)<<endl;

    cout<<"\n请输入要读取的行数:"<<endl;

    while(cin>>line)

    {

        cout<<"第"<<line<<"行的内容是 :"<<endl;

        cout<<ReadLine(filename,line);

        cout<<"\n\n请输入要读取的行数:"<<endl;

    }

}

/**********************************

程序运行情况如下:

该文件行数为:26

请输入要读取的行数:

-3

第-3行的内容是 :

Error 1: 行数错误,不能为0或负数。

请输入要读取的行数:

4

第4行的内容是 :

 4      d

请输入要读取的行数:

8

第8行的内容是 :

 8      h

请输入要读取的行数:

26

第26行的内容是 :

26      z

请输入要读取的行数:

33

第33行的内容是 :

Error 3: 行数超出文件长度。

请输入要读取的行数:

66

第66行的内容是 :

Error 3: 行数超出文件长度。

请输入要读取的行数:

^Z

**********************************/

2.5 读取数据到数组当中

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

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

//读取文件数据到临时数组

  

#include <iostream>

#include <fstream>

#include <string>

using namespace std;

  

  

int CountLines(char *filename)

{

    ifstream ReadFile;

    int n=0;

    string tmp;

    ReadFile.open(filename,ios::in);//ios::in 表示以只读的方式读取文件

    if(ReadFile.fail())//文件打开失败:返回0

    {

        return 0;

    }

    else//文件存在

    {

        while(getline(ReadFile,tmp,'\n'))

        {

            n++;

        }

        ReadFile.close();

        return n;

    }

}

int main()

{

    ifstream file;

    int LINES;

    char filename[512]="inFile.txt";

    file.open(filename,ios::in);

    if(file.fail())

    {

        cout<<"文件不存在."<<endl;

        file.close();

    }

    else//文件存在

    {

        LINES=CountLines(filename);

        int *tempInt=new int[LINES];

        char *tempChar=new char[LINES];

        int i=0;

        while(!file.eof()) //读取数据到数组

        {

  

            file>>tempInt[i];

            file>>tempChar[i];

            i++;

        }

        file.close(); //关闭文件

        for(i=0;i<LINES;i++)//输出数组内容

            cout<<tempInt[i]<<"\t"<<tempChar[i]<<endl;

        delete []tempInt;

        delete []tempChar;

    }

}

3.状态标志符的验证(Verification of state flags)

  • bad() 如果在读写过程中出错,返回 true
    例如:当我们要对一个不是打开为写状态的文件进行写入时,或者我们要写入的设备没有剩余空间的时候
  • fail()
    除了与bad() 同样的情况下会返回 true 以外,加上格式错误时也返回true ,例如当想要读入一个整数,而获得了一个字母的时候
  • eof()
    如果读文件到达文件末尾,返回true
  • good()
    这是最通用的:如果调用以上任何一个函数返回true 的话,此函数返回 false

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

4.获得和设置流指针(get and put stream pointers)

所有输入/输出流对象(i/o streams objects)都有至少一个流指针:

  • ifstream, 类似istream, 有一个被称为get pointer的指针,指向下一个将被读取的元素。
  • ofstream, 类似 ostream, 有一个指针 put pointer ,指向写入下一个元素的位置。
  • fstream, 类似 iostream, 同时继承了get 和 put

我们可以通过使用以下成员函数来读出或配置这些指向流中读写位置的流指针:

  • tellg() 和 tellp()
    这两个成员函数不用传入参数,返回pos_type 类型的值(根据ANSI-C++ 标准) ,就是一个整数,代表当前get 流指针的位置 (用tellg) 或 put 流指针的位置(用tellp).
  • seekg() 和seekp()
    这对函数分别用来改变流指针get 和put的位置。两个函数都被重载为两种不同的原型:

1

2

seekg ( pos_type position );

seekp ( pos_type position );

使用这个原型,流指针被改变为指向从文件开始计算的一个绝对位置。要求传入的参数类型与函数 tellg 和tellp 的返回值类型相同。

1

2

seekg ( off_type offset, seekdir direction );

seekp ( off_type offset, seekdir direction );

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

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

流指针 get 和 put 的值对文本文件(text file)和二进制文件(binary file)的计算方法都是不同的,因为文本模式的文件中某些特殊字符可能被修改。由于这个原因,建议对以文本文件模式打开的文件总是使用seekg 和 seekp的第一种原型,而且不要对tellg 或 tellp 的返回值进行修改。对二进制文件,你可以任意使用这些函数,应该不会有任何意外的行为产生。

使用样例:

1

2

3

4

5

6

例子:

file.seekg(0,ios::beg); //让文件指针定位到文件开头

file.seekg(0,ios::end); //让文件指针定位到文件末尾

file.seekg(10,ios::cur); //让文件指针从当前位置向文件末方向移动10个字节

file.seekg(-10,ios::cur); //让文件指针从当前位置向文件开始方向移动10个字节

file.seekg(10,ios::beg); //让文件指针定位到离文件开头10个字节的位置

获得一个二进制文件的大小:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

// obtaining file size 

   #include <iostream.h> 

   #include <fstream.h> 

      

   const char * filename = “test.txt”; 

      

   int main ()

    

       long l,m; 

       ifstream in(filename, ios::in|ios::binary); 

       l = in.tellg(); 

       in.seekg (0, ios::end); 

       m = in.tellg(); 

       in.close(); 

       cout << ”size of ” << filename; 

       cout << ” is ” << (m-l) << “ bytes.\n”; 

       return 0; 

   

     

  //结果: 

  size of example.txt is 40 bytes.

5.二进制文件

在二进制文件中,使用<< 和>>,以及函数(如getline)来操作符输入和输出数据,没有什么实际意义,虽然它们是符合语法的。

更多推荐