SSCANF读取1而不是3个浮点



我的lib具有可加载obj cem的功能...此功能的一部分

    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;

如果我将lib与main.cpp一起编译为可执行文件,则一切正常但是,如果我将lib编译为DLL,并尝试从另一个应用程序执行此函数,SSCANF Ingore最后2个Float,首先读取...如何解决此问题?

对不起,我可怕的英语..

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

尝试将&string[2]更改为string + 2
SSCANF的第一个参数应为char*(C-string)。

您的问题是您仅读取字符的数据。尝试以下代码:

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

c_str():获取c字符串等效

这不是答案,而是一个建议,太长时间了:

定义这些功能(注意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_2sscanf_3替换sscanf。如果SSCANF无法解析所需的字段数量,它将引发异常,您可以在程序中捕获该异常。这可能会帮助您弄清楚什么问题。

最新更新