C++ 从文件读取时字符串损坏
我正在用OpenGL做一些实验,并尝试加载一个着色器。它需要一个conchchar中的源,但是因为我在C++上做了,所以我可以使用STD::Stand,然后调用STR.cStReSo()。这不是问题所在-当我尝试读取文件时,它的读取效果非常好,但返回的值是一个损坏的字符串。以下是代码的相关部分:C++ 从文件读取时字符串损坏,c++,C++,我正在用OpenGL做一些实验,并尝试加载一个着色器。它需要一个conchchar中的源,但是因为我在C++上做了,所以我可以使用STD::Stand,然后调用STR.cStReSo()。这不是问题所在-当我尝试读取文件时,它的读取效果非常好,但返回的值是一个损坏的字符串。以下是代码的相关部分: // inline method on engine.hpp inline void readFile(std::string filePath, std::string* retValue) { s
// inline method on engine.hpp
inline void readFile(std::string filePath, std::string* retValue)
{
std::ifstream file;
file.open(filePath);
std::string result;
std::string line;
while (!file.eof())
{
std::getline(file, line);
result.append(line + "\n");
}
memcpy(retValue, &result, sizeof(result));
}
// implemented method on engine.cpp
GLint Engine::createShader(std::string vs, std::string fs)
{
GLuint vertex = glCreateShader(GL_VERTEX_SHADER);
GLuint fragment = glCreateShader(GL_FRAGMENT_SHADER);
std::string vsSourceStr = "";
std::string fsSourceStr = "";
readFile(vs, &vsSourceStr);
readFile(fs, &fsSourceStr);
const char* vsSource = vsSourceStr.c_str();
const char* fsSource = fsSourceStr.c_str();
//std::string t_vs = readFile(vs);
//const char* vsSource = readFile(vs).c_str();
//const char* fsSource = readFile(fs).c_str();
glShaderSource(vertex, 1, &vsSource, NULL);
glCompileShader(vertex);
glShaderSource(fragment, 1, &fsSource, NULL);
glCompileShader(fragment);
GLint program = glCreateProgram();
glAttachShader(program, vertex);
glAttachShader(program, fragment);
glLinkProgram(program);
if (shaderCompiled(program))
{
std::cout << "shader successfully compiled" << std::endl;
}
else
{
std::cout << "shader not compiled" << std::endl;
printShaderError(vertex);
printShaderError(fragment);
std::cout << "Vertex Shader source:" << std::endl;
std::cout << vsSource << std::endl;
std::cout << "Fragment Shader source:" << std::endl;
std::cout << fsSource << std::endl;
}
return program;
}
//engine.hpp上的内联方法
内联void readFile(std::string文件路径,std::string*retValue)
{
std::ifstream文件;
打开(文件路径);
std::字符串结果;
std::字符串行;
而(!file.eof())
{
std::getline(文件,行);
结果。追加(行+“\n”);
}
memcpy(retValue和result,sizeof(result));
}
//engine.cpp上的实现方法
闪烁引擎::createShader(标准::字符串vs,标准::字符串fs)
{
GLuint vertex=glCreateShader(GL_vertex_SHADER);
GLuint fragment=glCreateShader(GL_fragment_SHADER);
std::string vsSourceStr=“”;
std::string fsSourceStr=“”;
readFile(vs,&vsSourceStr);
readFile(fs和fsSourceStr);
const char*vsSource=vsSourceStr.c_str();
const char*fsSource=fsSourceStr.c_str();
//std::string t_vs=readFile(vs);
//const char*vsSource=readFile(vs).c_str();
//const char*fsSource=readFile(fs).c_str();
glShaderSource(顶点,1,&vsSource,NULL);
glCompileShader(顶点);
glShaderSource(fragment,1,&fsSource,NULL);
glCompileShader(片段);
闪烁程序=glCreateProgram();
glAttachShader(程序,顶点);
glAttachShader(程序,片段);
glLinkProgram(program);
if(着色器编写(程序))
{
std::cout这不会像你想的那样:
std::string line;
while (!file.eof())
{
std::getline(file, line);
result.append(line + "\n");
}
请使用:
std::string line;
while (std::getline(file, line))
{
result.append(line + "\n");
}
原因是直到读取文件后才会触发eof()
。这意味着您的std::getline()
可能已失败(在eof时),并且您正在使用错误的数据
请参阅:关于eof()
当您执行memcpy(retValue,&result,sizeof(result));
时,您复制的是内部std::string结构,而不是字符串数据。请指定字符串:*retValue=result
将结果字符串引用到readFile()将获得更健壮的版本:
void readFile(std::string filePath, std::string& retValue)
{
std::ifstream file(filePath);
retValue.clear();
std::string line;
while (std::getline(file, line))
{
retValue += line;
retValue += '\n';
}
}
GLint Engine::createShader(std::string vs, std::string fs)
{
GLuint vertex = glCreateShader(GL_VERTEX_SHADER);
GLuint fragment = glCreateShader(GL_FRAGMENT_SHADER);
std::string vsSourceStr;
std::string fsSourceStr;
readFile(vs, vsSourceStr);
readFile(fs, fsSourceStr);
// ...
}
将文件读入字符串的另一种方法是使用std::istreambuf\u迭代器
:
inline std::string readFile(std::string const& filename)
{
std::ifstream file(filename);
std::istreambuf_iterator<char> begin(file), end;
return std::string(begin, end);
}
inline std::string readFile(std::string const&filename)
{
std::ifstream文件(文件名);
istreambuf_迭代器开始(文件),结束;
返回标准::字符串(开始、结束);
}
您使用memcpy复制到std::string上的可能重复项是完全错误的。只需返回文件内容,您就完成了。IO可能比复制字符串花费的时间要长得多。谢谢!我不知道std::istreambuf_迭代器,非常有用。