首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >如何在C++中将整个文件读入std::string?

如何在C++中将整个文件读入std::string?
EN

Stack Overflow用户
提问于 2008-09-22 16:48:02
回答 20查看 100K关注 0票数 217

如何将文件读入std::string,即一次性读取整个文件?

文本或二进制模式应由调用方指定。该解决方案应该是符合标准的、可移植的和高效的。它不应该不必要地复制字符串的数据,并且应该避免在读取字符串时重新分配内存。

要做到这一点,一种方法是统计文件大小,将std::stringfread()调整为std::stringconst_cast<char*>()'ed data()。这要求std::string的数据是连续的,这不是标准所要求的,但似乎所有已知的实现都是这样的。更糟糕的是,如果文件是以文本模式读取的,则std::string的大小可能不等于文件的大小。

使用std::ifstreamrdbuf()可以构建一个完全正确的、符合标准的和可移植的解决方案到std::ostringstreamstd::string中。然而,这可能会复制字符串数据和/或不必要的内存重新分配。

  • 是否所有相关的标准库实现都足够智能,可以避免所有不必要的开销?
  • 是否有其他方法可以做到这一点?
  • 我是否错过了一些已提供所需functionality?

的隐藏Boost函数

代码语言:javascript
运行
AI代码解释
复制
void slurp(std::string& data, bool is_binary)
EN

回答 20

Stack Overflow用户

发布于 2008-09-22 17:22:30

一种方法是将流缓冲区刷新为单独的内存流,然后将其转换为std::string

代码语言:javascript
运行
AI代码解释
复制
std::string slurp(std::ifstream& in) {
    std::ostringstream sstr;
    sstr << in.rdbuf();
    return sstr.str();
}

这是非常简洁的。然而,正如问题中所指出的,这执行了一个冗余拷贝,不幸的是,根本没有办法消除这个拷贝。

不幸的是,避免冗余副本的唯一真正的解决方案是在循环中手动读取。由于C++现在保证了连续字符串,因此可以编写以下代码(≥C++14):

代码语言:javascript
运行
AI代码解释
复制
auto read_file(std::string_view path) -> std::string {
    constexpr auto read_size = std::size_t{4096};
    auto stream = std::ifstream{path.data()};
    stream.exceptions(std::ios_base::badbit);

    auto out = std::string{};
    auto buf = std::string(read_size, '\0');
    while (stream.read(& buf[0], read_size)) {
        out.append(buf, 0, stream.gcount());
    }
    out.append(buf, 0, stream.gcount());
    return out;
}
票数 153
EN

Stack Overflow用户

发布于 2009-02-07 19:27:07

关于类似的问题,请参阅this answer

为了您的方便,我重新发布了CTT的解决方案:

代码语言:javascript
运行
AI代码解释
复制
string readFile2(const string &fileName)
{
    ifstream ifs(fileName.c_str(), ios::in | ios::binary | ios::ate);

    ifstream::pos_type fileSize = ifs.tellg();
    ifs.seekg(0, ios::beg);

    vector<char> bytes(fileSize);
    ifs.read(bytes.data(), fileSize);

    return string(bytes.data(), fileSize);
}

当对《白鲸》(1.3M)的文本平均运行100次时,该解决方案的执行时间比这里提供的其他答案快了约20%。对于一个可移植的C++解决方案来说还不错,我想看看mmap文件的结果;)

票数 55
EN

Stack Overflow用户

发布于 2016-12-01 05:53:45

如果你有C++17 (std::filesystem),还有这种方法(它通过std::filesystem::file_size而不是seekgtellg来获取文件的大小):

代码语言:javascript
运行
AI代码解释
复制
#include <filesystem>
#include <fstream>
#include <string>

namespace fs = std::filesystem;

std::string readFile(fs::path path)
{
    // Open the stream to 'lock' the file.
    std::ifstream f(path, std::ios::in | std::ios::binary);

    // Obtain the size of the file.
    const auto sz = fs::file_size(path);

    // Create a buffer.
    std::string result(sz, '\0');

    // Read the whole file into the buffer.
    f.read(result.data(), sz);

    return result;
}

注意:如果你的标准库还不完全支持<experimental/filesystem>,你可能需要使用std::experimental::filesystem和C++17。如果result.data()不支持non-const std::basic_string data,你也可能需要用&result[0]替换它。

票数 32
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/116038

复制
相关文章
C++ 中的 std::string 类
theme: channing-cyan highlight: a11y-dark
鲸落c
2022/11/14
1.2K0
<c++ 常用代码块> | std::string 与 std::wstring转化
#include <string>#include <locale>#include <codecvt>// convert string to wstringinline std::wstring to_wide_string(const std::string& input){std::wstring_convert<std::codecvt_utf8<wchar_t>> converter;return converter.from_bytes(input);}// convert wstring t
IsEva
2022/12/05
1K0
如何在 Linux 中将 CSV 文件转换为 TSV 文件?
在Linux操作系统中,可以使用各种命令和工具来处理和转换文本文件。当需要将以逗号分隔的CSV文件转换为以制表符分隔的TSV文件时,可以使用一些简单的命令和技巧来实现。本文将详细介绍如何在Linux中将CSV文件转换为TSV文件。
网络技术联盟站
2023/06/20
1.2K0
如何在 Linux 中将 CSV 文件转换为 TSV 文件?
C++踩坑记录(一)std:;string的析构
越学C++越觉得自己菜了 之前写服务端程序有一个往消息队列里面推json的过程,然后发现推进去C#端取到的无论如何都是个空指针 简单复现一下现场
Pulsar-V
2019/04/01
2.3K0
C++头文件和std命名空间
C++ 是在C语言的基础上开发的,早期的 C++ 还不完善,不支持命名空间,没有自己的编译器,而是将 C++ 代码翻译成C代码,再通过C编译器完成编译。
芯动大师
2023/10/14
5340
C++头文件和std命名空间
Java中将Map转String,String转Map
但很多时候并不能直接将Map对象的toString() 而是应该转换为JsonObject后再调用toString()后存入就正常了
JavaEdge
2021/02/22
14.5K0
C++使用htslib库读入和写出bam文件
  有时候我们需要使用C++处理bam文件,比如取出read1或者read2等符合特定条件的序列,根据cigar值对序列指定位置的碱基进行统计或者对序列进行处理并输出等,这时我们可以使用htslib库。htslib可以用来处理SAM, BAM,CRAM 和VCF文件,是samtools、bcftools的核心库。 #include <stdio.h> #include <stdlib.h> #include <htslib/sam.h> using namespace std; #define bam
用户1680321
2018/04/28
2.2K0
C++使用htslib库读入和写出bam文件
如何在Linux中将文本内容追加到文件末尾?
在Linux中处理配置文件时,有时您需要将诸如配置参数之类的文本附加到现有文件中。追加只是意味着将文本添加到文件的末尾。
用户6543014
2020/03/06
14.7K0
如何在Linux中将文本内容追加到文件末尾?
std::string的拷贝赋值研究
说明:以下涉及的std::string的源代码摘自4.8.2版本。 结论:std::string的拷贝复制是基于引用计数的浅拷贝,因此它们指向相同的数据地址。 // std::string类定义 typedef basic_string string; template class basic_string { private:     // _Alloc_hider是模板类basic_string内嵌struct     struct _Alloc_hider :
一见
2019/03/20
3.5K0
std::string的find问题研究
一次偶然,发现完全同一份代码,在不同机器上find出现两个不同执行结果,本文旨在研究find的“诡异”行为,找出背后的原因。
一见
2018/12/27
1.5K0
c语言long类型转换成string,如何在C ++中将long转换为string?「建议收藏」
#include // … std::string number; std::stringstream strstream; strstream << 1L; strstream >> number;
全栈程序员站长
2022/08/28
2.5K0
c++中的std::stod, stCPP程序说明std::stod():stof, std::stold
如果未执行转换,则会引发invalid_argument异常。如果读取的值超出双精度的可表示值范围,则会引发out_of_range异常。无效的 idx 会导致未定义的行为。
鲸落c
2022/12/14
3K0
C++核心准则​​SL.str.1:使用std::string管理字符序列
string correctly handles allocation, ownership, copying, gradual expansion, and offers a variety of useful operations.
面向对象思考
2020/10/30
4980
C++核心准则​​SL.str.1:使用std::string管理字符序列
C++的std::transform()
在 C++ 标准库中,std::transform() 是一个非常有用的算法函数,它能够将给定范围中的每个元素进行变换,并将变换后的结果存储到另一个范围中。换句话说,它可以通过应用一个指定的操作函数来对容器范围内的元素进行转换。
叶茂林
2023/07/30
8180
如何把std::string当char *使用?
std::string使用很方便,但有时会碰到这样的问题,比如我们有一个结构体,内容如下所示:
王亚昌
2018/08/03
7170
C++的std::move()
std::move()是 C++ 标准库中的一个函数模板,用于将对象转换为右值引用,以便支持移动语义。它位于 <utility> 头文件中,并且是移动语义的关键工具之一。
叶茂林
2023/07/30
1K0
【Example】C++ 标准库 std::thread 与 std::mutex
与 Unix 下的 thread 不同的是,C++ 标准库当中的 std::thread 功能更加简单,可以支持跨平台特性。
芯片烤电池
2022/04/27
1.2K0
C++并发高级接口:std::async和std::future
std::async创建一个后台线程执行传递的任务,这个任务只要是callable object均可,然后返回一个std::future。future储存一个多线程共享的状态,当调用future.get时会阻塞直到绑定的task执行完毕:
racaljk
2018/08/31
1.6K0
C++并发低级接口:std::thread和std::promise
相比std::async,std::thread就原始多了。thread一定会创建新线程(而不是像async那样创建的时候可能不会,后面才创建新线程(std::launch::deferred)),并且创建它的线程还必须指定以何种策略等待新线程。
racaljk
2018/08/31
2.3K0
C++ std::stringstream「建议收藏」
(图片引用自cppreference),因此从std::ios_base等父类继承了大量成员函数。
全栈程序员站长
2022/09/05
5440

相似问题

将整个ASCII文件读入C++ std::string

99

如何将整个流读入std::string?

744

c++:如何将任何文件读入std::string

15

无法将文件内容读入std::string

11

如何在C++中将std::string转换为CV::String?

27
添加站长 进交流群

领取专属 10元无门槛券

AI混元助手 在线答疑

扫码加入开发者社群
关注 腾讯云开发者公众号

洞察 腾讯核心技术

剖析业界实践案例

扫码关注腾讯云开发者公众号
领券
社区富文本编辑器全新改版!诚邀体验~
全新交互,全新视觉,新增快捷键、悬浮工具栏、高亮块等功能并同时优化现有功能,全面提升创作效率和体验
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文