从中加载字符串时出现 sscanf 问题

sscanf problems when loading a string from it

本文关键字:sscanf 问题 加载 字符串      更新时间:2023-10-16

所以,我正在为我在OpenGL中的项目制作一个模型加载器。 我正在加载波前 OBJ 模型文件。 它加载得很好,但最大的问题是加载 MTL 文件时。

我使用 sscanf 从文件中读取数据。 MTL 材料在文件上告诉图像的名称。

像这样:map_Kd image.bmp

当我从文件中读取图像名称时出现问题。

我使用 LoadImage() 函数从位图文件中获取像素数据。 当我告诉它加载给定文件名时,它会抛出一条未处理的异常消息 ()。 是的,我在项目文件夹中有图像及其所有子文件夹,以防出现问题。

这是消息:

Unhandled exception at 0x57e1d51c (msvcr100d.dll) in OBJ MODEL LOADER.exe: 0xC0000005: Access violation reading location 0x622e656d.

这是我用来加载图像的函数:

GLuint load_texture(char* path)
{
GLuint tex;
HBITMAP bm = 0;
bm = (HBITMAP)LoadImage(NULL, path, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE | LR_CREATEDIBSECTION);
BITMAP b;
GetObject(bm, sizeof(b), &b);
glEnable(GL_TEXTURE_2D);
glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
glGenTextures(1, &tex);
glBindTexture(GL_TEXTURE_2D, tex);
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, b.bmWidth, b.bmHeight, 0, GL_BGR_EXT, GL_UNSIGNED_BYTE, b.bmBits);
return tex;
}

这是它获取图像名称的函数(等等...

void load_material(char* mtlpath, int loc, MODEL &m)
{
std::ifstream a(mtlpath);
std::vector<std::string*> file;
char buff[255];
if(!a.is_open())
{
MessageBox(g_hwnd, "Error when loading a specific material in the MTL file", "MTL(II) ERROR", 0);
}
while(!a.eof())
{
a.getline(buff, 255);
file.push_back(new std::string(buff));
}
char* name;
char* image;
GLuint ii;
sscanf(file[loc]->c_str(), "newmtl %c*",&name);
for(int i = loc; i < file.size(); i++)
{
if((file[i]->c_str()[0] == 'm'))// && (file[i]->c_str()[1] == 'a') && (file[i]->c_str()[2] == 'p') && (file[i]->c_str()[3] == '_') && (file[i]->c_str()[4] == 'K') && (file[i]->c_str()[5] == 'd'))
{
sscanf(file[i]->c_str(), "map_Kd %s", &image);
SetWindowText(g_hwnd, image);
break;
}
}
std::ofstream s("aa.txt");
s << image;
s.close();
ii = 0;
m.m.push_back(new material(name, image, ii));
a.close();
}

我已经尝试将%s(sscanf调用)更改为%*c,%c,%*c,%c[^]和其他多个。

我还必须提到,我试图直接将我的图像名称放在"image"变量中,而无需从文件中检索它,它就像那样完美地工作。

如何从字符串中成功检索映像名称?

顺便说一句,我不想使用任何其他东西(MCI,SDL);

简而言之:将std::vector<std::string*>替换为std::vector<std::string>,将scanf替换为std::stringstream

%c读取单个字符,但您尝试读取字符串,因此需要使用%s

%ssscanf()一起使用时,必须事先预先分配目标缓冲区,但您没有这样做。 您正在将未初始化的char*指针传递给sscanf(),因此它尝试将字符串数据写入随机内存,从而导致崩溃。

尝试更多类似的东西:

void load_material(char* mtlpath, int loc, MODEL &m)
{
std::ifstream a(mtlpath);
std::vector<std::string> file;
char buff[256];
if (!a.is_open())
{
MessageBox(g_hwnd, "Error when loading a specific material in the MTL file", "MTL(II) ERROR", 0);
}
while (a.getline(buff, 255))
{
buff[a.gcount()] = '';
file.push_back(buff);
}
a.close();
char name[256] = {0};
char image[256] = {0};
GLuint ii;
sscanf(file[loc].c_str(), "newmtl %255s", name);
for(int i = loc; i < file.size(); i++)
{
if (sscanf(file[i].c_str(), "map_Kd %255s", image) == 1)
{
SetWindowText(g_hwnd, image);
break;
}
}
std::ofstream s("aa.txt");
s << image;
s.close();
ii = 0;
m.m.push_back(new material(name, image, ii));
}

或者,摆脱sscanf(),在这种情况下您并不真正需要它:

void load_material(char* mtlpath, int loc, MODEL &m)
{
std::ifstream a(mtlpath);
std::vector<std::string> file;
std::string buff;
if (!a.is_open())
{
MessageBox(g_hwnd, "Error when loading a specific material in the MTL file", "MTL(II) ERROR", 0);
}
while (std::getline(a, buff))
file.push_back(buff);
a.close();
std::string name;
std::string image;
GLuint ii;
if (file[loc].compare(0, 7, "newmtl ", 7) == 0)
name = file[loc].substr(7);
for(int i = loc; i < file.size(); i++)
{
if (file[i].compare(0, 7, "map_Kd ", 7) == 0)
{
image = file[i].substr(7);
SetWindowText(g_hwnd, image.c_str());
break;
}
}
std::ofstream s("aa.txt");
s << image;
s.close();
ii = 0;
m.m.push_back(new material(name.c_str(), image.c_str(), ii));
}