C++ 中的字符串数组

发布于 2024-11-03 18:54:29 字数 3273 浏览 0 评论 0原文

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

到目前为止我可以做开线的工作。但是遍历每一行然后将它们记录到字符串数组(字符数组)中是非常困难的。请提供一些帮助。

这是我必须开始的一个示例:

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。那里容易多了。请帮忙。谢谢你!

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!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

鯉魚旗 2024-11-10 18:54:29

首先声明一个字符串数组(字符数组的数组)。您可以声明静态以避免重新分配。

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

然后

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

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;
                }
追星践月 2024-11-10 18:54:29

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

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)
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文