Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ember.js/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 从文件读取时字符串损坏_C++ - Fatal编程技术网

C++ 从文件读取时字符串损坏

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

我正在用OpenGL做一些实验,并尝试加载一个着色器。它需要一个conchchar中的源,但是因为我在C++上做了,所以我可以使用STD::Stand,然后调用STR.cStReSo()。这不是问题所在-当我尝试读取文件时,它的读取效果非常好,但返回的值是一个损坏的字符串。以下是代码的相关部分:

// 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_迭代器,非常有用。