帮我翻译Python代码,将文件名中的扩展名替换为C++

发布于 2024-09-09 01:18:36 字数 1396 浏览 7 评论 0原文

如果您对 Python 一无所知,我深表歉意,但是,以下代码片段对任何人来说都应该非常容易阅读。唯一需要注意的技巧 - 使用 [-1] 索引列表会给出最后一个元素(如果有),否则会引发异常。

>>> 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 不存在这些问题,因为 '.'"." 都是 Unicode 字符串(不是 "char" 类型)长度1,两者都只包含一个点。

请注意,返回类型是 void - 不必太担心。我不想让您厌倦我们如何将错误传达给用户的详细信息。在我的 Python 示例中,我只使用了断言。您可以执行类似的操作,或者仅包含注释,例如 // ERROR: [REASON]

如果有什么不清楚的地方请询问。使用 std::string 等而不是 CAtlString 作为函数参数的建议不是我想要的。如果需要,您可以在函数内转换它们,但我不希望在一个函数中混合不同的字符串类型。我正在 Windows 上使用 VS2010 编译这个 C++。这意味着我不会安装 BOOSTQTString 或其他开箱即用的库。窃取 boost 或其他标头来启用某些魔法也不是正确的解决方案。

谢谢。

I apologize if you know nothing about Python, however, the following snippet should be very readable to anyone. The only trick to watch out for - indexing a list with [-1] gives you the last element if there is one, or raises an exception.

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

I need to convert this logic into C++ (the language I am actually using, but so far suck at) function with the following signature: void PopulateBackupFileNameOrDie(CAtlString& strBackupFileName, CAtlString& strXmlFileName);. Here strXmlFileName is "input", strBackupFileName is "output" (should I reverse the oprder of the two?). The tricky part is that (correct me if I am wrong) I am working with a Unicode string, so looking for these characters: .xmlXML is not as straight-forward. Latest Python does not have these issues because '.' and "." are both Unicode strings (not a "char" type) of length 1, both contain just a dot.

Notice that the return type is void - do not worry much about it. I do not want to bore you with details of how we communicate an error back to the user. In my Python example I just used an assert. You can do something like that or just include a comment such as // ERROR: [REASON].

Please ask if something is not clear. Suggestions to use std::string, etc. instead of CAtlString for function parameters are not what I am looking for. You may convert them inside the function if you have to, but I would prefer not mixing different string types in one function. I am compiling this C++ on Windows, using VS2010. This implies that I WILL NOT install BOOST, QTString or other libraries which are not available out of the box. Stealing a boost or other header to enable some magic is also not the right solution.

Thanks.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

圈圈圆圆圈圈 2024-09-16 01:18:36

如果您使用 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");
  }
}

If you're using ATL why not just use CAtlString's methods?

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");
  }
}
屌丝范 2024-09-16 01:18:36

我没有像您的代码那样拆分字符串,因为这在 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;

I didn't split the string as your code does because that's a bit more work in C++ for really no gain (it's slower, and for this task you really don't need to do it).

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;
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文