2

目前我正在使用 C++ 环境进行非常基本的游戏。该游戏曾经是一个学校项目,但现在我完成了编程课,我想扩展我的技能并在这个旧任务上更加繁荣。

我已经做了很多我很满意的改变。我已将所有数据集中到文件夹层次结构中,并且我已经获得了读取这些位置的代码。

然而,我的问题源于一个一直困扰我的非常根本的缺陷。

为了访问我正在使用的图像数据,我使用了以下代码:

string imageLocation = "..\\DATA\\Images\\";

string bowImage = imageLocation + "bow.png";

问题是当玩家拿起游戏板上的物品时,我的代码应该使用以下代码:

hud.addLine("You picked up a " + (*itt)->name() + "!");

打印到命令行,“你拿起了弓!”。但相反,它显示“你拿起了一个 ..\DATA\Images\!”。

在我集中我曾经使用的数据之前:

name_(item_name.substr(0, item_name.find('.')))

在我的 Item 类构造函数中将项目名称砍成弓或蜡烛之类的东西。在我改变了我的数据的结构之后,我意识到我必须改变我将名字砍成同样简单的“弓”或“蜡烛”的方式。

我已更改上述代码以反映我对数据结构的更改为:

name_(item_name.substr(item_name.find("..\\DATA\\Images\\"), item_name.find(".png")))

但不幸的是,正如我之前提到的,这种代码更改并没有像我计划的那样工作。

所以现在我已经对我的问题进行了真正冗长的介绍,这是我的问题。

如何提取不需要的两个部分之间的字符串中间?此外,作为您目标的中间部分的长度未知。

非常感谢你们提供的任何帮助。如果您需要更多信息,请询问;我将非常乐意上传部分甚至我的整个代码以获得更多帮助。再次非常感谢您。

4

6 回答 6

7

老实说,您可能是从错误的角度来解决这个问题的。

您的项目类应该在私有成员中包含一个字符串“bow”。然后函数 Item::GetFilePath 将(在运行时)执行“..\DATA\Images\”+ this->name +“.png”。

“弓”项目对象的基本属性不是文件名 bow.png,而是它是“弓”这一事实。文件名只是一个派生的属性。

于 2008-12-15T10:41:46.633 回答
3

假设我理解正确,您的问题的简短版本是:如何拆分包含文件路径的字符串,以便删除路径和扩展名,只留下“标题”?

你需要find_last_of方法。这摆脱了路径:

std::size_type lastSlash = filePath.find_last_of('\\');
if (lastSlash == std::string::npos)
    fileName = filePath;
else
    fileName = filePath.substr(lastSlash + 1);

请注意,您可能需要定义一个常量\\,以防您需要为其他平台更改它。并非所有操作系统文件系统都\\用于分隔路径段。

另请注意,您还需要使用find_last_of扩展名点,因为文件名通常可以在其路径中包含点。只有最后一个表示扩展的开始:

std::size_type lastDot = fileName.find_last_of('.');
if (lastDot == std::string::npos)
{
    title = fileName;
}
else
{
    title = fileName.substr(0, lastDot);
    extension = fileName.substr(lastDot + 1);
}

请参阅http://msdn.microsoft.com/en-us/library/3y5atza0(VS.80).aspx

于 2008-12-15T08:40:15.037 回答
3

使用升压文件系统:

#include "boost/filesystem.hpp"

namespace fs = boost::filesystem;

void some_function(void)
{
    string imageLocation = "..\\DATA\\Images\\";
    string bowImage = imageLocation + "bow.png";
    fs::path image_path( bowImage  ); 
    hud.addLine("You picked up a " + image_path.filename() + "!");  //prints: You picked up a bow!
于 2008-12-15T10:25:54.357 回答
2

所以结合保罗和我的想法,尝试这样的事情(为了可读性而分解):

string extn = item_name.substr(item_name.find_last_of(".png"));
string path = item_name.substr(0, item_name.find("..\\DATA\\Images\\"));
name_ = item_name.substr( path.size(), item_name.size() - extn.size() );

如果您知道项目名称总是以“..DATA”等开头,您可以稍微简化一下您可以将它存储在一个常量中,而不需要在字符串中搜索它)

find_last_of编辑:按照 EarWicker 的建议,更改了要使用的扩展查找部分(这避免了您的路径在扩展之前的某处包含“.png”的情况)

于 2008-12-15T08:03:47.607 回答
1

item_name.find("..\DATA\Images\") 将返回子字符串 "..\DATA\Images\"开始的索引,但看起来你想要它结束的索引,所以你应该添加"..\DATA\Images\" 到 find 返回的索引的长度。

此外,正如 hamishmcn 指出的那样, substr 的第二个参数应该是要返回的字符数,我认为这将是“.png”开始的索引减去“..\DATA\Images\”结束的索引。

于 2008-12-15T07:26:24.640 回答
0

看起来不对的一件事是 substr 的第二个参数应该是要复制的字符数,而不是位置。

于 2008-12-15T07:22:50.793 回答