将文件转换为 char* 问题

Converting file to char* Issue

我是 C++ 编程的初学者,我遇到了一个问题。 我希望能够将文件的内容转换为 char*,并且我使用了文件流和字符串流。但是,它不起作用。

这是我的函数:

char* fileToChar(std::string const& file){

    std::ifstream in(file);
    if (!in){
        std::cout << "Error: file does not exist\n"; 
        exit(EXIT_FAILURE);
    }

    std::stringstream buffer;
    buffer << in.rdbuf() << std::flush;
    in.close();

    return const_cast<char *>(buffer.str().c_str());
}

然而,当我通过将其内容输出到另一个文件来测试该方法时,如下所示:

std::ofstream file("test.txt");
file << fileToChar("fileTest.txt");

我刚收到很多像这样的奇怪字符:

îþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþ[...etc]

这里到底发生了什么?有什么我错过的吗? 如果有更好的方法来做到这一点,我会很高兴知道!

return const_cast<char *>(buffer.str().c_str());

returns 指向本地 stringstream 内部缓冲区临时副本的内部字符缓冲区的指针。长话短说:一旦你退出这个函数,这个指针就会指向垃圾。

顺便说一句,即使这不是问题,const_cast 也是危险的废话,你不能通过指针 std::string::c_str returns 来写。 const_cast 的合法使用 极其 罕见。

更好的方法:最好和最简单的方法是返回 std::string。只有在不允许这样做的情况下,std::vector<char>(首选)或 new char[somelength](不赞成)才是可行的解决方案。

char* fileToChar(std::string const& file){

这一行已经表明有些事情正在朝着错误的方向发展。你 return 一个指向某个字符串的指针,如果 nullptr 可以 returned,依此类推。

如果你想要一个字符串,那么一定要使用 std::string!

std::string fileToChar(std::string const& file){
return const_cast<char *>(buffer.str().c_str());

另一条应该让所有警报都响起的线路。 const_cast 始终是解决某些潜在问题(或某些外部代码问题)的方法。

const 通常有一个很好的理由。通过强制编译器关闭 安全检查 并允许它尝试修改不可修改的数据,您通常会将编译错误变成难以诊断的 运行 时间错误。

即使如果此函数正常工作,任何修改结果的尝试都将是未定义的行为:

char* file_contents = fileToChar("foo.txt");
file_contents[0] = 'x'; // undefined behaviour

但无论如何它都无法正常工作。 buffer.str() return 是一个 临时 std::string 对象。 c_str() return 指向该临时对象的内部管理内存的指针。当计算完整表达式 return const_cast<char *>(buffer.str().c_str()) 时,对象的生命周期结束。因此,使用结果指针也是未定义的行为。


问题听起来很复杂,但解决起来很容易。使函数 return std::string 并将最后一条语句变为 return buffer.str();.

如果您的问题是如何将文件内容读入缓冲区,请考虑我的以下建议。但请注意缓冲区足够大以容纳文件内容。建议在调用 fileToChar().

之前检查文件大小并预分配内存
bool fileToChar(std::string const& file, char* buffer, unsigned int &buffer_size )
{
    FILE *f = fopen( file.c_str(), "rb" );

    if( f == nullptr )
    {
        return false;
    }

    fseek(f , 0, SEEK_END );

    const int size = ftell( f );

    rewind( f );
    fread( buffer, 1, size, f );
    fclose( f );

    return true;
}