将文件转换为 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;
}
我是 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;
}