迹忆客 专注技术分享

当前位置:主页 > 学无止境 > 编程语言 > C++ >

在 C++ 中将文件读入到字符串

作者:迹忆客 最近更新:2024/01/02 浏览次数:

本文将讲解几种在 C++ 中把文件内容读取到 std::string 的方法。


使用 istreambuf_iterator 在 C++ 中将文件读入到字符串

istreambuf_iterator 是一个输入迭代器,从 std::basic_streambuf 对象中读取连续的字符。因此,我们可以利用 istreambuf_iteratorifstream 流一起使用,并将文件的全部内容读取到 std::string 中。

首先,我们打开一个给定的文件路径作为 ifstream 对象。然后,我们可以将 istreambuf_iterator<char>(input_file) 传递给 string 构造函数,并在第一时间得到我们需要的对象。注意,我们是直接传递 string 构造函数语句,从函数中返回。程序的输出应该是由 filename 变量指定的文件内容。

#include <fstream>
#include <iostream>
#include <sstream>

using std::cerr;
using std::cout;
using std::endl;
using std::ifstream;
using std::ostringstream;
using std::string;

string readFileIntoString(const string& path) {
  ifstream input_file(path);
  if (!input_file.is_open()) {
    cerr << "Could not open the file - '" << path << "'" << endl;
    exit(EXIT_FAILURE);
  }
  return string((std::istreambuf_iterator<char>(input_file)),
                std::istreambuf_iterator<char>());
}

int main() {
  string filename("input.txt");
  string file_contents;

  file_contents = readFileIntoString(filename);
  cout << file_contents << endl;

  exit(EXIT_SUCCESS);
}

在 C++ 中使用 rdbuf 将文件读入字符串

rdbuf 函数是一个内置的方法,用来返回文件的流缓冲区的指针,这对于使用 << 运算符将文件的全部内容插入到需要的对象中是很有用的。

在下面的例子中,我们构造了一个 ostringstream 对象,在这个对象中插入 rdbuf 函数的返回值。函数本身返回的是 string 对象,所以使用 str 方法来获取最终的返回值。

#include <fstream>
#include <iostream>
#include <sstream>

using std::cerr;
using std::cout;
using std::endl;
using std::ifstream;
using std::ostringstream;
using std::string;

string readFileIntoString2(const string& path) {
  auto ss = ostringstream{};
  ifstream input_file(path);
  if (!input_file.is_open()) {
    cerr << "Could not open the file - '" << path << "'" << endl;
    exit(EXIT_FAILURE);
  }
  ss << input_file.rdbuf();
  return ss.str();
}

int main() {
  string filename("input.txt");
  string file_contents;

  file_contents = readFileIntoString2(filename);
  cout << file_contents << endl;

  exit(EXIT_SUCCESS);
}

使用 fread 将文件读入字符串

另一种读取文件的方法是 C 标准库函数 fread。这种方法需要相对较旧的函数,在现代 C++ 代码库中并不常见,但与以前的方法相比,它在速度方面有优势。

fread 需要四个参数。

  1. 一个指向存储读取数据的缓冲区的指针。
  2. 数据项的大小。
  3. 数据项的数量。
  4. 读取的文件指针。

由于我们要读的是整个文件,所以需要检索文件大小,并通过 Unix 系统调用 stat 实现。检索到文件大小后,我们将其值作为数据元素的大小传递给 fread 函数,并将数据项的数目指定为 1

需要注意的是,打开的文件需要用 fclose 函数调用来关闭,它的唯一参数是文件指针。

#include <fcntl.h>
#include <sys/stat.h>
#include <unistd.h>

#include <iostream>

using std::cerr;
using std::cout;
using std::endl;
using std::string;

string readFileIntoString3(const string& path) {
  struct stat sb {};
  string res;

  FILE* input_file = fopen(path.c_str(), "r");
  if (input_file == nullptr) {
    perror("fopen");
  }

  stat(path.c_str(), &sb);
  res.resize(sb.st_size);
  fread(const_cast<char*>(res.data()), sb.st_size, 1, input_file);
  fclose(input_file);

  return res;
}

int main() {
  string filename("input.txt");
  string file_contents;

  file_contents = readFileIntoString3(filename);
  cout << file_contents << endl;

  exit(EXIT_SUCCESS);
}

使用 read 将文件读成字符串

read 方法是符合 POSIX 标准的函数调用,在各种操作系统上都可以使用,如果程序员懂得有效地运用它,那么它可以成为最灵活的一种方法。fread 本身会在下面调用 read,但这并不能保证在所有情况下都有更快的操作,因为多种因素对这种系统调用的有效使用起着影响。

fread 的主要区别在于,read 需要一个文件描述符参数来指向从哪里读取数据的文件。文件描述符是与程序在执行过程中可能具有的打开的文件流相关联的特殊整数。它可以使用 open 函数调用获得,并以 int 类型存储。read 函数的另外两个参数是指向将存储数据的缓冲区的指针和需要读取的字节数,后者用 fstat 函数调用检索。注意,我们使用 string.data 作为缓冲区来存储读取的文件内容。

#include <fcntl.h>
#include <sys/stat.h>
#include <unistd.h>

#include <iostream>

using std::cerr;
using std::cout;
using std::endl;
using std::string;

string readFileIntoString4(const string& path) {
  struct stat sb {};
  string res;

  int fd = open(path.c_str(), O_RDONLY);
  if (fd < 0) {
    perror("open\n");
  }

  fstat(fd, &sb);
  res.resize(sb.st_size);
  read(fd, (char*)(res.data()), sb.st_size);
  close(fd);

  return res;
}

int main() {
  string filename("input.txt");
  string file_contents;

  file_contents = readFileIntoString4(filename);
  cout << file_contents << endl;

  exit(EXIT_SUCCESS);
}

转载请发邮件至 1244347461@qq.com 进行申请,经作者同意之后,转载请以链接形式注明出处

本文地址:

相关文章

Arduino 中停止循环

发布时间:2024/03/13 浏览次数:444 分类:C++

可以使用 exit(0),无限循环和 Sleep_n0m1 库在 Arduino 中停止循环。

Arduino 复位

发布时间:2024/03/13 浏览次数:315 分类:C++

可以通过使用复位按钮,Softwarereset 库和 Adafruit SleepyDog 库来复位 Arduino。

Arduino 的字符转换为整型

发布时间:2024/03/13 浏览次数:181 分类:C++

可以使用简单的方法 toInt()函数和 Serial.parseInt()函数将 char 转换为 int。

Arduino 串口打印多个变量

发布时间:2024/03/13 浏览次数:381 分类:C++

可以使用 Serial.print()和 Serial.println()函数在串口监视器上显示变量值。

Arduino if 语句

发布时间:2024/03/13 浏览次数:123 分类:C++

可以使用 if 语句检查 Arduino 中的不同条件。

Arduino ICSP

发布时间:2024/03/13 浏览次数:214 分类:C++

ICSP 引脚用于两个 Arduino 之间的通信以及对 Arduino 引导加载程序进行编程。

使用 C++ 编程 Arduino

发布时间:2024/03/13 浏览次数:127 分类:C++

本教程将讨论使用 Arduino IDE 在 C++ 中对 Arduino 进行编程。

Arduino 中的子程序

发布时间:2024/03/13 浏览次数:168 分类:C++

可以通过在 Arduino 中声明函数来处理子程序。

扫一扫阅读全部技术教程

社交账号
  • https://www.github.com/onmpw
  • qq:1244347461

最新推荐

教程更新

热门标签

扫码一下
查看教程更方便