将文件内容读入 C++ 中的字符串

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2912520/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-28 11:28:38  来源:igfitidea点击:

Read file-contents into a string in C++

c++stringfile-io

提问by sonofdelphi

Possible Duplicate:
What is the best way to slurp a file into a std::string in c++?

可能的重复:
在 C++ 中将文件放入 std::string 的最佳方法是什么?

In scripting languages like Perl, it is possible to read a file into a variable in one shot.

在 Perl 等脚本语言中,可以一次性将文件读入变量。

    open(FILEHANDLE,$file);
    $content=<FILEHANDLE>;

What would be the most efficient way to do this in C++?

在 C++ 中执行此操作的最有效方法是什么?

回答by Maik Beckmann

Like this:

像这样:

#include <fstream>
#include <string>

int main(int argc, char** argv)
{

  std::ifstream ifs("myfile.txt");
  std::string content( (std::istreambuf_iterator<char>(ifs) ),
                       (std::istreambuf_iterator<char>()    ) );

  return 0;
}

The statement

该声明

  std::string content( (std::istreambuf_iterator<char>(ifs) ),
                       (std::istreambuf_iterator<char>()    ) );

can be split into

可以分为

std::string content;
content.assign( (std::istreambuf_iterator<char>(ifs) ),
                (std::istreambuf_iterator<char>()    ) );

which is useful if you want to just overwrite the value of an existing std::string variable.

如果您只想覆盖现有 std::string 变量的值,这很有用。

回答by M. Williams

The most efficient, but not the C++ way would be:

最有效但不是 C++ 的方式是:

   FILE* f = fopen(filename, "r");

   // Determine file size
   fseek(f, 0, SEEK_END);
   size_t size = ftell(f);

   char* where = new char[size];

   rewind(f);
   fread(where, sizeof(char), size, f);

   delete[] where;

#EDIT - 2

#编辑 - 2

Just tested the std::filebufvariant also. Looks like it can be called the best C++ approach, even though it's not quite a C++ approach, but more a wrapper. Anyway, here is the chunk of code that works almost as fast as plain C does.

也刚刚测试了该std::filebuf变体。看起来它可以被称为最好的 C++ 方法,尽管它不是一种 C++ 方法,而更像是一个包装器。无论如何,这里的代码块几乎和普通 C 一样快。

   std::ifstream file(filename, std::ios::binary);
   std::streambuf* raw_buffer = file.rdbuf();

   char* block = new char[size];
   raw_buffer->sgetn(block, size);
   delete[] block;

I've done a quick benchmark here and the results are following. Test was done on reading a 65536Kbinary file with appropriate (std::ios:binaryand rb) modes.

我在这里做了一个快速基准测试,结果如下。测试是在读取具有适当 (和) 模式的65536K二进制文件时完成的。std::ios:binaryrb

[==========] Running 3 tests from 1 test case.
[----------] Global test environment set-up.
[----------] 4 tests from IO
[ RUN      ] IO.C_Kotti
[       OK ] IO.C_Kotti (78 ms)
[ RUN      ] IO.CPP_Nikko
[       OK ] IO.CPP_Nikko (106 ms)
[ RUN      ] IO.CPP_Beckmann
[       OK ] IO.CPP_Beckmann (1891 ms)
[ RUN      ] IO.CPP_Neil
[       OK ] IO.CPP_Neil (234 ms)
[----------] 4 tests from IO (2309 ms total)

[----------] Global test environment tear-down
[==========] 4 tests from 1 test case ran. (2309 ms total)
[  PASSED  ] 4 tests.

回答by Martin York

The most efficient is to create a buffer of the correct size and then read the file into the buffer.

最有效的方法是创建一个正确大小的缓冲区,然后将文件读入缓冲区。

#include <fstream>
#include <vector>

int main()
{
    std::ifstream       file("Plop");
    if (file)
    {
        /*
         * Get the size of the file
         */
        file.seekg(0,std::ios::end);
        std::streampos          length = file.tellg();
        file.seekg(0,std::ios::beg);

        /*
         * Use a vector as the buffer.
         * It is exception safe and will be tidied up correctly.
         * This constructor creates a buffer of the correct length.
         * Because char is a POD data type it is not initialized.
         *
         * Then read the whole file into the buffer.
         */
        std::vector<char>       buffer(length);
        file.read(&buffer[0],length);
    }
}

回答by Draco Ater

There should be no \0in text files.

\0文本文件中应该没有。

#include<iostream>
#include<fstream>

using namespace std;

int main(){
  fstream f(FILENAME, fstream::in );
  string s;
  getline( f, s, '
unsigned int FileRead( std::istream & is, std::vector <char> & buff ) {
    is.read( &buff[0], buff.size() );
    return is.gcount();
}

void FileRead( std::ifstream & ifs, string & s ) {
    const unsigned int BUFSIZE = 64 * 1024; // reasoable sized buffer
    std::vector <char> buffer( BUFSIZE );

    while( unsigned int n = FileRead( ifs, buffer ) ) {
        s.append( &buffer[0], n );
    }
}
'); cout << s << endl; f.close(); }

回答by Draco Ater

This depends on a lot of things, such as what is the size of the file, what is its type (text/binary) etc. Some time ago I benchmarked the following function against versions using streambuf iterators - it was about twice as fast:

这取决于很多事情,例如文件的大小是什么,它的类型是什么(文本/二进制)等。前段时间我使用流缓冲迭代器对以下函数的版本进行了基准测试 - 它的速度大约是其两倍:

#include<iostream>
#include<vector>
#include<iterator>

main(int argc,char *argv[]){
  // read standard input into vector:
  std::vector<char>v(std::istream_iterator<char>(std::cin),
                     std::istream_iterator<char>());
  std::cout << "read " << v.size() << "chars\n";
}

回答by catwalk

maybe not the most efficient, but reads data in one line:

也许不是最有效的,但在一行中读取数据:

ifstream file("file", ios::binary);
string fileStr;

istreambuf_iterator<char> inputIt(file), emptyInputIt
back_insert_iterator<string> stringInsert(fileStr);

copy(inputIt, emptyInputIt, stringInsert);

回答by academicRobot

Here's an iterator-based method.

这是一个基于迭代器的方法。

##代码##