C++ 意外的ifstream行为?
我正在尝试将GLSL顶点/片段着色器源加载到用于OpenGL的const char*数组中。我使用的函数是C++ 意外的ifstream行为?,c++,C++,我正在尝试将GLSL顶点/片段着色器源加载到用于OpenGL的const char*数组中。我使用的函数是 const char* loadSource(const char* path) { string line; stringstream output; ifstream source(path); if(source.is_open()) { while(source.good()) { getline(
const char* loadSource(const char* path)
{
string line;
stringstream output;
ifstream source(path);
if(source.is_open())
{
while(source.good())
{
getline(source, line);
output << line << endl;
}
source.close();
}
return output.str().c_str();
}
注意:我尝试将vs_源代码直接编码到*.cpp文件中,并编译了两个着色器。这指出了我在loadSource函数中一定做了一些愚蠢的事情
问题:是什么导致了文本输入的这种奇怪行为
是什么导致了文本输入的这种奇怪行为
当函数loadSource
返回output
超出范围时,返回指向局部变量的指针vs\u source/fs\u source
是悬空指针。对vs\u source/fs\u source
的访问具有未定义的行为
要解决问题,可以返回std::string:
std::string loadSource(const char* path)
{
//...
return output.str();
}
std::string vs_source = loadSource("vertex.vert"); // vs_source loads fine
std::string fs_source = loadSource("fragment.frag");
从函数返回结果时,将创建一个悬空引用:
return output.str().c_str();
在表达式末尾,从流中获取的临时std::string
将被销毁,返回的内存将变得无效:对数组的任何访问都将导致未定义的bahvior
顺便说一句,这种输入方法是错误的:
while(source.good())
{
getline(source, line);
output << line << endl;
}
。。。当然,
out
应该声明为std::ostringstream
(而不是额外的o
)。为什么每个人都坚持逐行读取文件?只是其实很简单:
std::string LoadFile(const std::string &filename)
{
std::ifstream file (filename.c_str());
if (file) {
std::ostringstream os;
os << file.rdbuf();
return os.str();
}
else {
// error
}
}
std::string加载文件(const std::string和filename)
{
std::ifstream文件(filename.c_str());
如果(文件){
std::ostringstream os;
os非常感谢,这非常有帮助-我也非常感谢这些提示。顺便说一句:使用std::endl而不是“\n”到底有什么错?@vojtahavlíček:主要是性能问题的常见来源。有关更多详细信息,请参阅此。谢谢!尽管@Dietmar也提出了这一建议,但您的帖子很好地澄清了这一点(希望我能投票:)。顺便问一下:检查file.Is_open()和简单的file之间有什么优势吗?
while(source.good())
{
getline(source, line);
output << line << endl;
}
while (std::getline(source, line)) {
output << line << '\n';
}
out << source.rdbuf();
std::string LoadFile(const std::string &filename)
{
std::ifstream file (filename.c_str());
if (file) {
std::ostringstream os;
os << file.rdbuf();
return os.str();
}
else {
// error
}
}