如何返回null终止const char *的向量?

时间:2015-07-21 05:10:36

标签: c++ pointers const

我正在尝试逐行读取文件。 将每一行转换为以空字符结尾的字符串。 将所有行推入向量并返回。

vector<const char*> TypeGLscene::LoadGLshader (string ThisFile)
{
ifstream fromFile;
fromFile.open(ThisFile);
if (fromFile.good()==false)
{
    cout<<"Could not find file: "<<ThisFile<<endl;
    exit(1);
}

vector<const char*>  FileContents;
const char*    OneLine;
string         LineStr;

while (fromFile.good()==true)
{
    getline(fromFile,LineStr);
    OneLine = LineStr.c_str();
    FileContents.push_back(OneLine);
}

fromFile.close();
return FileContents;

问题是所有的char字符串都是在堆栈中创建的,函数会返回char *的向量。

我试图通过以下方式在堆上分配内存:

OneLine = new char[LineStr.size()+1];

但是我被卡住了,因为一旦分配了我就无法复制任何东西了;内容是常量。

我怎么能在const char *上使用new关键字并在它实现它之前的同时向它添加内容?

(更不用说我必须逐个删除它们,另一方面......真是一团糟)

编辑: 我宁愿返回一个向量,但这一切都是因为我不知道将一个向量转换为const char **的快速(一行)方法:

void glShaderSource(GLuint shader,
                    GLsizei count,
                    const GLchar **string,
                    const GLint *length);

3 个答案:

答案 0 :(得分:5)

回归std::vector<char*>充满了问题。

  1. 您必须为每一行分配内存。该函数的客户端必须添加代码以释放内存。客户端代码变得比它需要的更复杂。

  2. 客户端功能必须知道char*是使用malloc还是operator new分配的。他们必须根据用于分配内存的方法遵循适当的内存释放方法。客户再一次知道该功能的作用以及它是如何做到的。

  3. 更好的方法是只返回std::vector<std::string>

    std::vector<std::string>  FileContents;
    std::string LineStr;
    
    while (fromFile.good()==true)
    {
        getline(fromFile,LineStr);
        FileContents.push_back(LineStr);
    }
    
    fromFile.close();
    return FileContents;
    

    如果您必须返回std::vector<char*>,则可以使用:

    std::vector<char*>  FileContents;
    std::string LineStr;
    
    while (fromFile.good()==true)
    {
        getline(fromFile,LineStr);
        char* line = new char[LineStr.size()+1];
        strcpy(line, LineStr.c_str());
        FileContents.push_back(line);
    }
    
    fromFile.close();
    return FileContents;
    

答案 1 :(得分:1)

您可以转换然后从

中调用C ++ 11中的std::cout
glShaderSource
使用

std::vector<std::string> vec;

了解C ++ 11 std::vector::data&amp; std::transform

我在你的(OpenGL?)库中假设{ std::vector<const Glchar*> veccstr = std::transform(vec.begin(), vec.end(), [](const std::string&s){ return static_cast<const Flchar*>(s.c_str()); }); glShaderSource(shader, veccstr.size(), veccstr.data(), &length); } ,或者至少

typedef char Flchar;

BTW我们都知道static_assert("Flchar same size as char", sizeof(Flchar) == sizeof(char)); 始终为1,因此您可以在sizeof(char)

中代码sizeof(Flchar)==1

答案 2 :(得分:0)

结合Sahu和Jerem的建议我完全改变了策略并简单地返回(从文件读取功能)一个字符串,每个着色器行有换行符:

string TypeGLscene::LoadGLshader (string ThisFile)
{
   ifstream fromFile;
   fromFile.open(ThisFile);
   if (fromFile.good()==false)
   {
       cout<<"Could not find file: "<<ThisFile<<endl;
       exit(1);
   }

   string  FileContents, oneLine;

   while (fromFile.good()==true)
   {
       getline(fromFile,oneLine);
       FileContents += (oneLine + "\n");
   }
   fromFile.close();
   //FileContents=FileContents.c_str();
   return FileContents;
}

然后只将一个字符串输入到glshaderSource

char* ShaderChapters[1]; ShaderChapters[0]=&fileContent[0];
GLuint VertexShaderID = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(VertexShaderID,1,ShaderChapters,0);
glCompileShader(VertexShaderID);

尽管如此,考虑到原始问题的措辞,Sahu的回答仍然是最准确的。