Помогите мне перевести код Python, который заменяет расширение в имени файла на C ++ - PullRequest
4 голосов
/ 10 июля 2010

Я прошу прощения, если вы ничего не знаете о 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 я просто использовал assert. Вы можете сделать что-то подобное или просто добавить комментарий, например // ERROR: [REASON].

Пожалуйста, спросите, если что-то не ясно. Рекомендации по использованию std::string и т. Д. Вместо CAtlString для параметров функции - это не то, что я ищу. Вы можете преобразовать их внутри функции, если нужно, но я бы предпочел не смешивать разные типы строк в одной функции. Я собираю этот C ++ на Windows, используя VS2010. Это означает, что я НЕ БУДУ устанавливать BOOST, QTString или другие библиотеки, которые недоступны из коробки. Кража boost или другого заголовка для включения какой-либо магии также не является правильным решением.

Спасибо.

Ответы [ 2 ]

6 голосов
/ 12 июля 2010

Если вы используете 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");
  }
}
3 голосов
/ 10 июля 2010

Я не разбивал строку, как это делает ваш код, потому что это немного больше работы в C ++, потому что он действительно не дает никакой выгоды (это медленнее, и для этой задачи вам действительно не нужно это делать).*

...