C++ 从中加载字符串时出现sscanf问题
所以,我在用OpenGL为我的项目制作一个模型加载器。 我正在加载波前OBJ模型文件。 它可以很好地加载,但最大的问题是加载MTL文件时 我使用sscanf从文件中读取数据。 MTL材质在文件上显示图像的名称 类似于:C++ 从中加载字符串时出现sscanf问题,c++,string,winapi,opengl,std,C++,String,Winapi,Opengl,Std,所以,我在用OpenGL为我的项目制作一个模型加载器。 我正在加载波前OBJ模型文件。 它可以很好地加载,但最大的问题是加载MTL文件时 我使用sscanf从文件中读取数据。 MTL材质在文件上显示图像的名称 类似于:map\u Kd image.bmp 当我从文件中读取图像名称时,问题就出现了 我使用LoadImage()函数从位图文件中获取像素数据。 当我告诉它加载给定的文件名时,它抛出一条未处理的异常消息()。 是的,我在项目文件夹及其所有子文件夹中都有该图像,以防出现问题 这是一条信息:
map\u 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_材料(char*mtlpath,int loc,MODEL&m)
{
std::ifa流(mtlpath);
std::矢量文件;
字符buff[255];
如果(!a.是开着的())
{
MessageBox(g_hwnd,“在MTL文件中加载特定材料时出错”,“MTL(II)错误”,0);
}
而(!a.eof())
{
a、 getline(buff,255);
file.push_back(新std::string(buff));
}
字符*名称;
字符*图像;
GLuint ii;
sscanf(文件[loc]->c_str(),“newmtl%c*”,&name);
对于(int i=loc;ic_str()[0]='m'))/&(文件[i]->c_str()[1]='a')&(文件[i]->c_str()[2]='p')&(文件[i]->c_str()[3]='u')&(文件[i]->c_str 4]='K')&(文件[i]->c_str 5]='d'))
{
sscanf(文件[i]->c_str(),“map_Kd%s”,&image);
SetWindowText(g_hwnd,图像);
打破
}
}
std::流s(“aa.txt”);
简而言之,将std::vector
替换为std::vector
,将scanf
替换为std::stringstream%c
读取单个字符,但您试图读取字符串,因此需要使用%s
将%s
与sscanf()
一起使用时,必须预先分配目标缓冲区,但您没有这样做。您正在将未初始化的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()] = '\0';
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));
}
stringstream如何为我做这项工作?请更好地解释,谷歌搜索std::stringstream,你会发现很多使用它的例子。我很确定你最不想要的是一个%c
格式字符串。它将读取一个字符(这个字符包括其他格式类型忽略的空白).s
%s
至少去掉了前导空格。由于与加载程序结构不兼容的问题,它不能很好地工作。使用char image[255]使其几乎无法使用。它表明sscanf没有返回任何内容。图像仍然为空;无需担心。我找到了完美的解决方案。它是.substr和.find_的最后一个。无论如何,谢谢。@HelderArmando:很难说,因为您没有显示任何实际解析的数据。
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()] = '\0';
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));
}
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));
}