如何返回以空结尾的const char*的向量

How to return a vector of null terminated const char*?

本文关键字:结尾 const char 向量 何返回 返回      更新时间:2023-10-16

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

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*类型的vector。

我试图在堆上分配内存:

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

但是我卡住了,因为一旦分配,我不能复制任何东西;内容为const.

我怎么能在const char*上使用new关键字,同时在它意识到它是const之前给它添加内容呢?

(更不用说我必须一个接一个地删除它们,另一方面……真乱)

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

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

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

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

  2. 客户端函数必须知道char*是使用malloc还是operator new分配的。它们必须遵循基于用于分配内存的方法的内存释放的适当方法。再一次,客户端负担过重,知道太多的函数做什么和它是如何做到的。

更好的方法是只返回一个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;

你可以在c++ 11中将glShaderSource

转换为
std::vector<std::string> vec;
使用

{
  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);
}

阅读c++ 11 std::vector::data &std::变换

我假设typedef char Flchar;在你的某处(OpenGL?)库,或至少

static_assert("Flchar same size as char", sizeof(Flchar) == sizeof(char));

顺便说一句,我们都知道sizeof(char)总是1,所以你可以在static_assert

中编写sizeof(Flchar)==1

结合Sahu和Jerem的建议,我完全改变了策略,简单地返回(从文件读取函数)单个字符串,每个shader行带有换行符:

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的回答仍然是最准确的。