简体   繁体   中英

Array of Strings in C++

I'm a trying to translate into C++ a small Python program I have that opens an OBJ file and records necessary data into Classes of FACES and VERTS. In the Python program, it simply looks at each line and splits them into tokens delineated by spaces. If the line starts with an "f" the succeeding tokens would be data for faces. For "v", position of verts. For "vt", UV info. "vn" normals for verts.

So far I could do the line for line opening. But to go through each line and then record them into an Array of Strings (char array), is so difficult. Some help please.

Here's a sample of what I have to start with:

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++;
        } 
    }

Instead of having a "SWITCH" in which previously set variables for "MODE" I'd rather have something as simple as:

   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

But that's PYTHON. So much easier there. Please help. Thank you!

OBJ parsing can be kind of painful; you should look at stringstream objects. Just to give a short example of concrete use for your needs:

//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)
    }
}

First declare a Strings Array (array of char arrays). You can declare static in order to avoid reallocate.

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

Then

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM