我是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());
另一行应该让所有警报都熄灭。stringstream
0总是解决一些潜在问题(或外部代码的一些问题)的方法。
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;
}