2010-07-09 19 views
4

如果您對Python一無所知,我表示歉意,但是,下面的代碼段對任何人都應該是非常易讀的。唯一值得注意的技巧 - 使用[-1]爲列表編制索引,如果有最後一個元素,則會提供給您最後一個元素,或引發異常。幫我翻譯替換文件名中的擴展名的Python代碼到C++

>>> fileName = 'TheFileName.Something.xMl' 
>>> fileNameList = fileName.split('.') 
>>> assert(len(fileNameList) > 1) # Must have at least one period in it 
>>> assert(fileNameList[-1].lower() == 'xml') 
>>> fileNameList[-1] = 'bak' 
>>> fileName = '.'.join(fileNameList) 
>>> print(fileName) 
TheFileName.Something.bak 

我需要這個邏輯轉換成C++(我實際使用的語言,但到目前爲止,吮吸)具有以下簽名功能:void PopulateBackupFileNameOrDie(CAtlString& strBackupFileName, CAtlString& strXmlFileName);。這裏strXmlFileName是「輸入」,strBackupFileName是「輸出」(我是否應該顛倒兩者的操作符?)。棘手的部分是(糾正我,如果我錯了)我正在處理一個Unicode字符串,所以尋找這些字符:.xmlXML是不是很直截了當。最新的Python沒有這些問題,因爲'.'"."都是長度爲1的Unicode字符串(不是"char"類型),都包含一個點。

請注意,返回類型爲void - 不必太擔心。我不想讓你知道我們如何將錯誤傳達給用戶。在我的Python例子中,我只使用了一個斷言。你可以做這樣的事情,或只是包括一個評論,如// ERROR: [REASON]

請問是否有不清楚的地方。建議使用std::string等而不是CAtlString作爲函數參數,這不是我正在尋找的。如果你需要,你可以在函數內部轉換它們,但是我不希望在一個函數中混合不同的字符串類型。我正在使用VS2010在Windows上編譯這個C++。這意味着我不會安裝BOOSTQTString或其他無法使用的庫。偷一個boost或其他標題來啓用一些魔法也不是正確的解決方案。

謝謝。

+0

誰投了我票 - 請告訴我爲什麼我的問題是愚蠢的。 – 2010-07-09 22:30:10

+0

我沒有投票給你,但他們可能做到了,因爲你要求其他人只是做你的工作,而不是給你一個提示。 – 2010-07-10 00:34:42

+0

看起來我只是可能不得不在這一個懸賞。 – 2010-07-10 02:01:01

回答

6

如果您使用的是ATL,爲什麼不使用CAtlString的方法呢?

CAtlString filename = _T("TheFileName.Something.xMl"); 

//search for '.' from the end 
int dotIdx = filename.ReverseFind(_T('.')); 

if(dotIdx != -1) { 
    //extract the file extension 
    CAtlString ext = filename.Right(filename.GetLength() - dotIdx); 

    if(ext.CompareNoCase(_T(".xml")) == 0) { 
    filename.Delete(dotIdx, ext.GetLength()); //remove extension 
    filename += _T(".bak"); 
    } 
} 
+0

好東西,如果有效的話,我喜歡它。讓我測試它。順便說一下:愚蠢的問題:是或不是Unicode? – 2010-07-12 13:41:39

+0

是的,你對比CompareNoCase是對的,對此抱歉,修正了它。 – Praetorian 2010-07-12 17:36:27

+1

至於Unicode與否,對於Visual Studio項目,這取決於您的項目設置;具體是否定義了UNICODE宏。 ATL具有字符串轉換功能,可以將UTF-8轉換爲UTF-16並返回,搜索MSDN中的「ATL 7.0字符串轉換類和宏」,它們被稱爲CW2A(),CT2W()等。 – Praetorian 2010-07-12 17:56:21

3

我並沒有像你的代碼那樣分割字符串,因爲在C++中這樣做確實沒有任何收穫(速度較慢,對於這個任務你真的不需要這麼做)。

string filename = "TheFileName.Something.xMl"; 
size_t pos = filename.rfind('.'); 
assert(pos > 0 && pos == filename.length()-4); // the -4 here is for length of ".xml" 
for(size_t i = pos+1; i < filename.length(); ++i) 
    filename[i] = tolower(filename[i]); 
assert(filename.substr(pos+1) == "xml"); 
filename = filename.substr(0,pos+1) + "bak"; 
std::cout << filename << std::endl; 
+0

好,你在C++編碼時顯然不需要用Python思考。 'string'是Unicode嗎?如何將'CAtlString'轉換爲'string'?它是一個'std :: string'嗎?另外,你在哪裏將''XmL''轉換爲小寫? – 2010-07-09 22:14:51

+0

對不起,我不熟悉ATL,所以我不知道如何轉換爲一個std ::字符串。 std :: string不是unicode,但是std :: wstring是。雖然使用wstring有點棘手,因爲您不能直接將它與字符串文字(即「xml」)進行比較。你需要使用一些其他代碼來做到這一點.... – SoapBox 2010-07-09 22:21:28

+0

std :: string可以是Unicode;它可以保存任何8位編碼的字符,包括UTF-8。 – JWWalker 2010-07-18 01:49:12

相關問題