c++中要进行文件的读入,首先要包含一个头文件 fstream

输出到文件

为打开一个可供输出的文件需要定义一个ofstream 对象并将文件名传入:

std::ofstream out("out.txt");

在不做任何其他操作的情况下,如果该文件不存在就会创建一个相应文件,如果存在就会打开并将原来文件中的信息全部覆盖。如果想要不覆盖原文件而仅仅是在文件的末尾加上要输出的信息,只需要在定义ofstream对象的时候传入第二个参数std::ios_base::app以打开追加模式(append_mode):

std::ofstream out_with_append("out.txt", std::ios_base::app);

此外由于文件可能会打开失败,所以需要用if判断文件是否打开成功。

#include <fstream>
#include <iostream>

int main () {
  //输入到文件
  std::ofstream out("out.txt");
  if (!out) {
    std::cerr << "error in out" << std::endl;
  } else {
    std::cerr << "successfully open out file" << std::endl;
    out << "Hello world!" << std::endl;
  }
  std::ofstream out_with_append("out.txt", std::ios_base::app);
  if (!out_with_append) {
    std::cerr << "error in out_with_append" << std::endl;
  } else {
    std::cerr << "successfully open out_with_append file" << std::endl;
    out_with_append << "Hello world again!" << std::endl;
  }
  return 0;
}

这其中std::endl是事先定义好的操作符,由iostream library 提供,他的作用是插入一个换行符并清除输出缓冲区(output buffer)的内容。

从文件中读入

要打开一个可供读入的文件,需要先定义一个ifstream对象并将供于读入的文件传入:

std::ifstream in("out.txt");

同样的文件依然可能会无法正常打开,所以也需要用if判断一下文件是否打开成功。

下面在上面代码的基础上增添ifstream的功能

#include <fstream>
#include <iostream>
#include <string>

int main () {
    //输出到文件
    std::ofstream out("out.txt");
    if (!out) {
        std::cerr << "error in out" << std::endl;
    } else {
        std::cerr << "successfully open out file" << std::endl;
        out << "Hello world!" << std::endl;
    }
    std::ofstream out_with_append("out.txt", std::ios_base::app);
    if (!out_with_append) {
        std::cerr << "error in out_with_append" << std::endl;
    } else {
        std::cerr << "successfully open out_with_append file" << std::endl;
        out_with_append << "Hello world again!" << std::endl;
    }
    //从文件中读入
    std::ifstream in("out.txt");
    if (!in) {
        std::cerr << "error in in" << std::endl;
    } else {
        std::cerr << "successfully open in file" << std::endl;
        std::string s;
        while (in >> s) {
            std::cout << s;
        }
    }
    return 0;
}

这里控制台的全部输出内容为

successfully open out file
successfully open out_with_append file
successfully open in file
Helloworld!Helloworldagain!
Process finished with exit code 0

首先注意到这里在in >> s外面套了一层while,原因是每次读入在没有读到文件末尾的时候 in >> s会返回一个 in,而当读到文件末尾的时候会返回false,因此可以在while的循环表达式中作为结束的标志。

其次会发现输出的内容和输入的内容不一样,原因我引用了下面一段解释

因为istream_iterator的自增的副作用等价于相应流通过>>操作符读一个T类型的数据,而istream通过>>操作符读一个字符类型(这里就是char)的数据会跳过前面的空白字符

这里的空白字符不仅包括了空格,还包括换行符。

ofstream一样,ifstream同样也有追加模式。为了以追加模式打开文件需要传入第二个参数std::ios::bash::in|std::ios::bash::app :

std::ifstream in("out.txt", std::ios_base::in|std::ios_base::app);

这里需要注意的是以追加模式打开文件会默认在文件的末尾,如果没有重新先定位就读取文件内容,那么就会立即遇到文件结束(EOF)的情况。seekg()可以将in重新定位到文件的起始处。

追加模式作用?

#include <fstream>
#include <iostream>
#include <string>

int main () {
    //输出到文件
    std::ofstream out("out.txt");
    if (!out) {
        std::cerr << "error in out" << std::endl;
    } else {
        std::cerr << "successfully open out file" << std::endl;
        out << "Hello world!" << std::endl;
    }
    std::ofstream out_with_append("out.txt", std::ios_base::app);
    if (!out_with_append) {
        std::cerr << "error in out_with_append" << std::endl;
    } else {
        std::cerr << "successfully open out_with_append file" << std::endl;
        out_with_append << "Hello world again!" << std::endl;
    }
    //从文件中读入
    std::ifstream in("out.txt", std::ios_base::in|std::ios_base::app);
    in.seekg(0);
    if (!in) {
        std::cerr << "error in in" << std::endl;
    } else {
        std::cerr << "successfully open in file" << std::endl;
        std::string s;
        while (in >> s) {
            std::cout << s;
        }
        std::cout << std::endl;
        out_with_append << "append text" << std::endl;
        in >> s;
        std::cout << s << std::endl;
    }
    return 0;
}