2008-12-15 129 views
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('.'))) 

在我的項目類的構造函數的項目名稱印章,只是像弓或蠟燭。在我改變了我的數據結構之後,我意識到我將不得不改變我如何將這個名字切成同樣簡單的'弓'或'蠟燭'。

我已經改變了上面的代碼,以反映我在數據結構的變化是:

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

但不幸的是,因爲我先前提到的這個代碼改變是不工作,以及我計劃的那樣。

所以,現在我已經給出了真正的漫長的介紹我的問題是什麼,這是我的問題。

如何提取兩個部分之間不需要的字符串的中間部分?此外,你的目標的中間部分是未知的長度。

非常感謝您爲您提供的任何幫助。如果您需要更多信息,請詢問;我將非常樂意上傳部分甚至是全部代碼以獲得更多幫助。再次非常感謝你。

回答

0

看起來有錯的一件事是substr的第二個參數應該是要複製的字符數,而不是位置。

1

item_name.find(「.. \ DATA \ Images \」)將返回子字符串「.. \ DATA \ Images \」開始的索引,但似乎您希望索引位於該索引處結束,因此您應該將「.. \ DATA \ Images \」的長度添加到find返回的索引。

另外,正如hamishmcn指出的那樣,substr的第二個參數應該是要返回的字符數,這將是「.png」開始的索引減去「.. \ DATA \ Images \」結束的索引, 我認爲。

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'在擴展名之前的某處)

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); 

請注意,你可能想萬一定義常量爲\\你需要改變它的其他平臺。並非所有的OS文件系統都使用\\來分隔路徑段。

另外請注意,您還需要使用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

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! 
7

在所有honeasty,你可能會從錯誤的臨近結束這。

你的項目類應該有一個字符串「弓」,在一個私有成員。功能項目:: GetFilePath然後會(在運行時)做 「.. \ DATA \圖片\」 +這個 - >名稱+ 「巴紐」。

的「弓」項目對象的基本屬性不是文件名bow.png,但事實證明,這是一個「弓」。文件名只是一個派生特權。