正在将文件转换为char*问题



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

这就是我的功能:

char* fileToChar(std::string const& file){
    std::ifstream in(file);
    if (!in){
        std::cout << "Error: file does not existn"; 
        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());

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

顺便说一句,即使这不是问题,const_cast也会是危险的无稽之谈,不允许通过std::string::c_str返回的指针进行写入。const_cast的合法使用极为罕见。

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

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

这条线已经表明有些东西正朝着错误的方向发展。您返回一个指向某个字符串的指针,函数的用户完全不清楚谁负责释放分配的内存,是否必须释放内存,是否可以返回nullptr,等等

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

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

另一行应该让所有警报都熄灭。stringstream0总是解决一些潜在问题(或外部代码的一些问题)的方法。

const通常是有充分理由的。通过强制编译器关闭安全检查并允许其尝试修改不可修改的数据,通常可以将编译错误转化为难以诊断的运行时错误。

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

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

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


问题听起来很复杂,但解决起来很容易。使函数返回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;
}

最新更新