sscanf读取1而不是3浮动

时间:2014-03-13 15:12:00

标签: c++ scanf

我有lib用于加载obj网格的功能... 这个功能的一部分

    case 'v':
        if(string[1] == ' ')
        {
            have_verticles = true;
            tmp_Vertex.set(0,0,0);
            sscanf(&string[2],"%f %f %f",&tmp_Vertex.x,&tmp_Vertex.y,&tmp_Vertex.z);
            Verticles.push_back(tmp_Vertex);
        }
        else if(string[1] == 't')
        {
            have_texcoords = true;
            tmp_Texcoord.set(0,0);
            sscanf(&string[2],"%f %f",&tmp_Texcoord.x,&tmp_Texcoord.y);
            TexCoords.push_back(tmp_Texcoord);
        }
        else if(string[1] == 'n')
        {
            have_normals = true;
            tmp_Normal.set(0,0,0);
            sscanf(&string[2],"%f %f %f",&tmp_Normal.x,&tmp_Normal.y,&tmp_Normal.z);
            Normals.push_back(tmp_Normal);
        }
        break;

如果我使用main.cpp编译lib作为可执行文件,一切正常 但如果我将lib编译为DLL并尝试从另一个应用程序执行此函数, sscanf ingore最后2个浮点数并且只读取第一个...... 如何解决这个问题?

对不起我可怕的英语..

UPD:

示例文件(部分)

v 1.000000 -1.000000 -1.000000
v 1.000000 -1.000000 1.000000
v -1.000000 -1.000000 1.000000
v -1.000000 -1.000000 -1.000000
v 1.000000 1.000000 -0.999999
v 0.999999 1.000000 1.000001
v -1.000000 1.000000 1.000000
v -1.000000 1.000000 -1.000000

sscanf只读取第一个花车...

UPD2: 字符串是

char string[256];
带有输入字符串

的sscanf()之后
"1.000000 -1.000000 -1.000000"   
tmp_Vertex.x = 1.0 tmp_Vertex.y = 0.0 tmp_Vertex.z = 0.0

sscanf()返回1 ..

全功能代码......

renderer::IMesh* CMeshOBJImporter::LoadOBJ(io::IFile* file)
{
    bool have_verticles = false;
    bool have_texcoords = false;
    bool have_normals   = false;

    std::vector<core::vector3f> Verticles;
    std::vector<core::vector2f> TexCoords;
    std::vector<core::vector3f> Normals;
    std::vector<core::vector3s> Indices;

    core::vector3f tmp_Vertex;
    core::vector2f tmp_Texcoord;
    core::vector3f tmp_Normal;
    core::vector3s tmp_Index;

    char string[256];
    while(read_string(file,string) != 0)
    {
        switch(string[0])
        {
        case '#':
            continue;
        case 'o':
            continue;
        case 'm':
            continue;
        case 'u':
            continue;
        case 'v':
            if(string[1] == ' ')
            {
                have_verticles = true;
                tmp_Vertex.set(0,0,0);
                sscanf(string + 2,"%f %f %f",&tmp_Vertex.x,&tmp_Vertex.y,&tmp_Vertex.z);
                Verticles.push_back(tmp_Vertex);
            }
            else if(string[1] == 't')
            {
                have_texcoords = true;
                tmp_Texcoord.set(0,0);
                sscanf(&string[2],"%f %f",&tmp_Texcoord.x,&tmp_Texcoord.y);
                TexCoords.push_back(tmp_Texcoord);
            }
            else if(string[1] == 'n')
            {
                have_normals = true;
                tmp_Normal.set(0,0,0);
                sscanf(&string[2],"%f %f %f",&tmp_Normal.x,&tmp_Normal.y,&tmp_Normal.z);
                Normals.push_back(tmp_Normal);
            }
            break;
        case 'f':
            std::vector<core::vector3s> Face;

            char* tok = strtok(&string[1]," \n");
            while(tok != NULL)
            {
                tmp_Index.set(0,0,0);

                if(have_verticles && !have_texcoords && !have_normals)
                    sscanf(tok,"%d",&tmp_Index.x);
                else if(have_verticles && have_texcoords && !have_normals)
                    sscanf(tok,"%d/%d",&tmp_Index.x,&tmp_Index.y);
                else if(have_verticles && !have_texcoords && have_normals)
                    sscanf(tok,"%d//%d",&tmp_Index.x,&tmp_Index.z);
                else if(have_verticles && have_texcoords && have_normals)
                    sscanf(tok,"%d/%d/%d",&tmp_Index.x,&tmp_Index.y,&tmp_Index.z);

                tmp_Index.add(-1);
                Face.push_back(tmp_Index);
                tok = strtok(NULL," \n");
            }
                //Triangulate face
                if(Face.size() > 3)
                {
                    //!< If Face = Quad we use predefined vertex positions (it's faster)
                    //!< Else we split big polygon(more than 4 vertex) on triangles

                    if(Face.size() == 4)
                    {
                        Face.push_back(0);
                        Face.push_back(0);
                        Face[4] = Face[3];
                        Face[3] = Face[2];
                        Face[5] = Face[0];
                    }
                    else
                    {
                        std::vector<core::vector3s> TriangulatedFaces;
                        u32 FaceSize = Face.size()-2;
                        for(u32 i = 0; i < FaceSize; i++)
                        {
                            TriangulatedFaces.push_back(Face[0  ]);
                            TriangulatedFaces.push_back(Face[1+i]);
                            TriangulatedFaces.push_back(Face[2+i]);
                        }
                        Face.clear();
                        Face.insert(Face.end(),TriangulatedFaces.begin(),TriangulatedFaces.end());
                    }
                }
                Indices.insert(Indices.end(),Face.begin(),Face.end());
                break;
            }
        }

        renderer::CVertexArray* VertexArray = new renderer::CVertexArray();

        u32 IndicesSize = Indices.size();
        for(u32 i = 0; i < IndicesSize; i++)
        {
            renderer::SVertex Vertex;

            if(have_verticles)
                Vertex.Position = Verticles[Indices[i].x];
            if(have_texcoords)
                Vertex.TexCoord = TexCoords[Indices[i].y];
            if(have_normals)
                Vertex.Normal   =   Normals[Indices[i].z];

            VertexArray->addVertex(Vertex);
        }

        u32 VertexFormat = renderer::EVF_VERTEX;
        if(have_texcoords)
            VertexFormat |= renderer::EVF_TEXCOORD;
        if(have_normals)
            VertexFormat |= renderer::EVF_NORMAL;


        VertexArray->setPrimitiveType(renderer::EPT_TRIANGLES);
        VertexArray->setVertexFormat(VertexFormat);

        renderer::IMesh* newMesh = new renderer::CMesh(VertexArray,NULL);
        VertexArray->release();

        return newMesh;
    }

3 个答案:

答案 0 :(得分:0)

尝试将&string[2]更改为string + 2 sscanf的第一个参数应该是char*(C字符串)。

答案 1 :(得分:0)

您的问题是您只能从角色中读取数据。 请尝试以下代码:

sscanf(string.c_str(),"%f %f %f",&tmp_Vertex.x,&tmp_Vertex.y,&tmp_Vertex.z);

c_str():获取等效的C字符串

答案 2 :(得分:0)

这不是一个答案,而是一个建议,太长时间无法发表评论:

定义这些函数(注意to_string是c ++ 11)

using std::string;
using std::to_string;

void sscanf_2( const char* str, const char* fmt, float *f1, float *f2 ) {
    size_t n = sscanf(str,fmt, f1, f2 );
    if (n != 2) throw std::runtime_error("sscanf_2: bad parse, str="+string(str)+" fmt="+string(fmt)+" n="+to_string(n));
}

void sscanf_3( const char* str, const char* fmt, float *f1, float *f2, float *f3 ) {
    size_t n = sscanf(str,fmt, f1, f2, f3 );
    if (n != 3) throw std::runtime_error("sscanf_3: bad parse, str="+string(str)+" fmt="+string(fmt)+" n="+to_string(n));
}

在代码中使用这些功能,将sscanf替换为sscanf_2sscanf_3。如果sscanf无法解析所需数量的字段,它将抛出异常,您可以在程序中捕获该异常。这可能有助于你弄清楚出了什么问题。