2010-07-09 20 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

相关问题