Pointer arithmetic in sscanf function

I'm modifying an OpenGL ms3d model viewer in wxDev-C++ to also load another 3D model format.

The new model format appears to use a different winding order for front faces than ms3d files.

Rather than switching between glFrontFace(GL_CW) and glFrontFace(GL_CCW) for each format I wanted to change the winding order manually of the other format when the file is read.

1
2
3
4
5
6
7
8
9
10
11
12
#define SIZE_STR 256
struct ms3d_triangle_t
{
	unsigned short flags;
	unsigned short vertexIndices[3];
	float vertexNormals[3][3];
	float s[3];
	float t[3];
	float normal[3];
	unsigned char smoothingGroup;
	unsigned char groupIndex;
};


The following code works but has the front faces incorrect.

1
2
3
4
5
6
7
8
9
//loop over all triangles
char *pStr;
fgets(buf,SIZE_STR,fp);
ms3d_triangle_t *tri = new ms3d_triangle_t;
if ( (pStr = strstr(buf,"V(")) != NULL ) 
{
    sscanf(pStr,"V(%d %d %d)",tri->vertexIndices,(tri->vertexIndices)+1,(tri->vertexIndices)+2);
}
delete tri;


If I try the following to change the winding the model is not drawn correctly since tri->vertexIndices[2] is always 0.

I have solved the problem using temp variables in the sscanf function and then assigning separately to tri->vertexIndices[i] but am curious why this code didn't work.

1
2
3
4
5
6
7
8
9
//loop over all triangles
char *pStr;
fgets(buf,SIZE_STR,fp);
ms3d_triangle_t *tri = new ms3d_triangle_t;
if ( (pStr = strstr(buf,"V(")) != NULL ) 
{
    sscanf(pStr,"V(%d %d %d)",tri->vertexIndices,(tri->vertexIndices)+2,(tri->vertexIndices)+1);
}
delete tri;


Hm. Well, %d makes scanf() and friends look for an int pointer, and you passed a short pointer. Each time an element is set, another is getting stepped on, since int is usually twice as big as short.
Because stdio functions are variadic, there's no way to make this check at compile time. I'd recommend using C++ stream functions instead.
Thanks for your explanation.

I will study C++ stream functions and use %hu instead of %d in the meantime.
Topic archived. No new replies allowed.