C++ 意外的ifstream行为?

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(

我正在尝试将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(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
    }
}