gpt4 book ai didi

c++ - 文件输入和指针所有权语义

转载 作者:行者123 更新时间:2023-11-28 00:17:35 26 4
gpt4 key购买 nike

我知道有两种方法可以将文件内容读取为 C 风格的字符串。我需要 C 风格的字符串而不是 unique_ptr<string> 的原因是因为我会将此数据传递给 C 函数, gumbo_parse() 其参数是 C 风格的字符串,这样我就避免了 unique_ptr<string> 的开销.我愿意接受反对我的决定的争论。

std::ifstream ifs(bf::path("..."));                                              // Input file stream

第一种方式:

std::filebuf * ptr_fbuff = ifs.rdbuf();                                         // Buffer to file contents.
std::size_t fbuff_size = ptr_fbuff->pubseekoff(0, ifs.end, std::ios_base::in); // Get offset from 0 to end of buffer.
ptr_fbuff->pubseekpos(0, std::ios_base::in); // Move buffer position back to beginning.
char * buffer = new char[fbuff_size]; // Buffer to store file data.
ptr_fbuff->sgetn(buffer, fbuff_size); // Get file data.

第二种方式:

std::stringstream sstm_buffer;                                                  // Buffer to file contents.
sstm_buffer << ifs.rdbuf(); // Read file contents to sstm.
const std::string & str_buffer = sstm_buffer.str(); // Get underlying string from sstm.
char * buffer = new char[str_buffer.size()]; // Buffer to store file data.
str_buffer.copy(buffer, str_buffer.size()); // Copy file contents to buffer.

做事:

GumboOutput * ptr_outpt = gumbo_parse(buffer);
//...

关闭文件:

gumbo_destroy_output(&kGumboDefaultOptions, ptr_outpt);
ifs.close(); // Close stream to file.
delete[] buffer; // Delete allocated buffer.

两者在内存成本和速度方面有何不同。很明显,一个在将内容放入 C 风格字符串之前使用 Stringstream 作为缓冲区,而另一个在将内容放入 C 风格字符串之前使用 filebuf。

现在回答我的第二个问题。所有权语义和内存分配。 ifstream 是否在堆中为从 rdbuf 返回的缓冲区分配任何内存?我是否负责删除从 rdbuf 返回的缓冲区?如果没有,假设我正在读取一个巨大的文件...这不是有可能在堆栈中存储大量数据吗?

编辑:

std::unique_ptr<std::string> mytype::my_func(const std::string & path)
{
std::ifstream ifs(path); // Input file stream
std::stringstream sstm_buffer; // Buffer to file contents.
sstm_buffer << ifs.rdbuf(); // Read file contents to sstm.
ifs.close(); // Close stream to file.
auto ptr_buffer = std::make_unique<std::string>(sstm_buffer.str()); // Pointer to copy of sstm buffer contents.
return std::move(ptr_buffer); // Return pointer.
}

编辑2:

std::string mytype::my_func(const std::string & path) const
{
std::ifstream ifs(path);
std::stringstream sstm_buf;
sstm_buf << ifs.rdbuf();
ifs.close();
return sstm_buf.str();
}

编辑3:

std::string psclient::file_get(const std::string & path) const
{
std::ifstream ifs(path); // Stream to file (Automatically close() on ~).
std::ostringstream reader; // Stream to read file contents.
reader << ifs.rdbuf(); // Read in file contents.
return reader.str(); // Return a move instead of copy (Done implicitly).
}

最佳答案

The reason I need a C-style string and not a unique_ptr is because I will be passing this data to a C function

你仍然可以获得一个C风格的指针,例如

#include <iostream>
#include <string>
#include <memory>

void print_C_style_string(const char* psz)
{
printf("str = %s", psz);
}

int main()
{
std::unique_ptr<std::string> p{new std::string{"This is a string!"}};
print_C_style_string(p.get()->c_str());
return 0;
}

unique_ptr 没有开销。摘自 Bjarne Stroustrup 的“The C++ Programming Language”:

unique_ptr is a very lightweight mechanism with no space or time overhead compared to correct use of a built-in pointer.

将文件逐行读入字符串的简单方法:

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

using namespace std;

int main()
{
ifstream fin("my_file.txt", ios::in);
if(!fin){
printf("Error opening file.");
return 1;
}

while(fin.peek() != EOF){
string s;
getline(fin, s);
cout << s << std::endl;
}

fin.close();

return 0;
}

关于c++ - 文件输入和指针所有权语义,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29290494/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com