【问题标题】:Array of Strings in C++C++ 中的字符串数组
【发布时间】:2011-08-12 20:18:51
【问题描述】:

我正在尝试将我拥有的一个小型 Python 程序翻译成 C++,它打开一个 OBJ 文件并将必要的数据记录到 FACES 和 VERTS 类中。在 Python 程序中,它只是查看每一行并将它们拆分为由空格描述的标记。如果该行以“f”开头,则后续标记将是面部数据。对于“v”,顶点的位置。对于“vt”,UV 信息。 verts 的“vn”法线。

到目前为止,我可以为线路开通做线路。但是要遍历每一行,然后将它们记录到一个字符串数组(char 数组)中,是非常困难的。请帮忙。

这是我必须开始的示例:

FILE * pFile;
char myString[100];
pFile = fopen(filename, "r");
while(fgets(myString, 100, pFile)!=NULL) {
        char *sep;
        int counter = 0;
        int mode = 0;
        sep = strtok(myString, " ");
        while (sep != NULL) {
            if (strncmp(sep,"f",1)==0) {
                mode = 4;
            } else {
            if (strncmp(sep,"vn",2)==0) {
                mode = 3;
            } else {
            if (strncmp(sep,"vt",2)==0) {
                mode = 2;
            } else {
            if (strncmp(sep,"v",2)==0) {
                mode = 1;
            }else {

            }
            }
            }
            }
            switch (mode) {
                case 1 :{
                    // vertex position
                    break;
                }
                case 2 :{
                    cout << sep << " --> vertex normal" << endl;
                    break;
                }
                case 3 :{
                    cout << sep << " --> vertex UV" << endl;
                    break;
                }
                case 4 :{
                    cout << sep << " --> face " << endl;
                    break;
                }
            }
            sep = strtok(NULL, " ");
            counter++;
        } 
    }

我宁愿有一个简单的东西,而不是之前为“MODE”设置变量的“SWITCH”:

   def openFile(self, filename):
    faceCount = 0
    for line in open(filename, "r"):
        vals = line.split()
        if len(vals) > 0:
            if vals[0] == "v":
                v = map(float, vals[1:4])
                self.verts.append(Point(v[0], v[1], v[2]))
            if vals[0] == "vn":
                n = map(float, vals[1:4])
                self.norms.append(Normal(n[0], n[1], n[2]))
            if vals[0] == "vt":
                vt = map(float, vals[1:3])
                self.text.append(UV(vt[0], vt[1]))

            if vals[0] == "f":
                vertsOut = []
                normsOut = []
                textOut = []
                for f in vals[1:]:

                    w = f.split("/")
                    # OBJ Files are 1-indexed so we must subtract 1 below
                    try:
                        vertsOut.append(self.verts[int(w[0])-1])
                    except:
                        print "Issue with Position of Face %s " % faceCount
                    try:
                        textOut.append(self.text[int(w[1])-1])
                    except:
                        print "Issue with UV of Face %s " % faceCount
                    try:
                        normsOut.append(self.norms[int(w[2])-1])
                    except:
                        print "Issue with Normal of Face %s " % faceCount

                    self.verts[int(w[0])-1].addFace(faceCount)

                self.faces[faceCount]= Face(vertsOut,normsOut,textOut)
                faceCount += 1

但那是 Python。那里容易得多。请帮忙。谢谢!

【问题讨论】:

  • 你应该看看else if,你现在在你的C代码中硬编码它们:p。
  • 你从哪本书学习 C++?
  • 你必须非常小心面部定义和'/'分隔符。如果面的顶点是法线的,那么定界符是'//'而不是单个'/'。见OBJ file format。顺便问一下,您对任何答案都满意吗?

标签: c++ arrays string dynamic


【解决方案1】:

首先声明一个Strings Array(char数组的array)。您可以声明静态以避免重新分配。

char *array[100] //Supposing you need 100 positions in the array

然后

switch (mode) {
                case 1 :{
                    // vertex position
                    array[counter] = strdup(myString);
                    break;
                }

【讨论】:

  • 不,不要这样做。使用 std::string,永远​​不要使用完全非标准的 strdup 函数。
【解决方案2】:

OBJ 解析可能有点痛苦;您应该查看stringstream 对象。 仅举一个满足您需求的具体用途的简短示例:

//Read the .obj file line by line
std::string line;
float x, y, z;
std::vector<Vertex> vertices;
std::vector<Face>   faces;
while (std::getline(file_in, line))
{
    std::istringstream stream (line);
    std::string line_token;
    stream  >> line_token;

    if(line_token == "v")
    {
        stream >> x >> y >> z;
        vertices.push_back(Vertex(x,y,z));
    }
    //manage normals & tangents (vn & vt) the exact same way

    else if(line_token == "f")
    {
        Face f;
        FaceVertex vtx;
        int tmp_v;
        while (stream >> tmp_v)
        {
            //Store the vertex index
            vtx.setID(--tmp_v); //-- vector index starts at 0
            char c = 0;
            std::string elt;
            stream >> elt;
            //Assert that the next char is "/"
            if (elt [0] == '/')
            {
                if (elt [1] == '/')
                {
                    elt.erase(0, 2);
                    std::istringstream part_stream(elt);
                    //Store the Vertex Normal
                    part_stream >> tmp_v;
                    vtx.setNormalID(--tmp_v);
                }
                else
                {
                    elt.erase(0, 1);
                    std::istringstream part_stream(elt);
                    //Store the VertexUV index
                    part_stream >> tmp_v;
                    vtx.setUVID(--tmp_v);
                    c = 0;
                    part_stream >> c;
                    if(c == '/')
                    {
                        part_stream >> tmp_v;
                        vtx.setNormalID(--tmp_v);
                    }
                }
            }
            f.addVertex(vtx);
        }
        faces.push_back(f)
    }
}

【讨论】:

  • 字符串流..太棒了!我会调查的。谢谢你的例子。我现在正在消化。美妙美妙!
猜你喜欢
  • 2013-08-16
  • 2011-01-22
  • 1970-01-01
  • 1970-01-01
  • 2012-03-20
  • 2018-04-02
  • 2015-03-27
  • 1970-01-01
相关资源
最近更新 更多