我有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];
"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;
}
答案 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_2
或sscanf_3
。如果sscanf无法解析所需数量的字段,它将抛出异常,您可以在程序中捕获该异常。这可能有助于你弄清楚出了什么问题。