Когда мы должны предпочесть строки с расширенными символами?

Я модернизирую большую устаревшую кодовую базу MFC, которая содержит настоящую смесь строковых типов:

  • CString
  • std :: string
  • std :: wstring
  • символ *
  • wchar_t *
  • _bstr_t

Я хотел бы стандартизировать один строковый тип внутри и преобразовывать в другие типы только тогда, когда это абсолютно необходимо сторонним API (то есть функциями COM или MFC). Вопрос, который обсуждаем я и мои коллеги; какой тип строки мы должны стандартизировать?

Я бы предпочел одну из стандартных строк C ++: std :: string или std :: wstring. Я лично склоняюсь к std :: string, потому что нам не нужны широкие символы - это внутренняя кодовая база без пользовательского пользовательского интерфейса (т.е. нет необходимости в поддержке нескольких языков). «Простые» строки позволяют нам использовать простые строковые литералы без украшений («Привет, мир» против L «Привет, мир» или _T («Привет, мир»)).

Есть ли официальная позиция сообщества программистов? Когда вы сталкиваетесь с несколькими типами строк, что обычно используется в качестве стандартного «внутреннего» формата хранения?


person BTownTKD    schedule 31.08.2017    source источник
comment
UTF8 везде приходит в голову. Но Windows не поддерживает UTF8. Однако обратите внимание, что вам действительно следует рассматривать имена файлов как отдельные типы. Использование ускорения может быть хорошим выбором.   -  person MSalters    schedule 31.08.2017
comment
Внутренняя версия Windows - UTF-16LE, поэтому std::wstring хорошо подходит для этой платформы; так std::vector<wchar_t>.   -  person Richard Critten    schedule 31.08.2017
comment
Для приложения Windows используйте std::wstring. С узкими строками вам понадобятся преобразования повсюду. Примечание: поскольку вы этого еще не знаете, вы не лучший выбор для человека, который будет выполнять эту работу, это основы. В этом выборе виноват ваш менеджер.   -  person Cheers and hth. - Alf    schedule 31.08.2017
comment
Windows предоставляет альтернативы узким символам почти для всех API. Преобразования в коде не потребуются. Они могут исполняться за кулисами, но это не проблема. Это пахнет преждевременными микрооптимизациями.   -  person BTownTKD    schedule 31.08.2017
comment
Что касается _T("Hello world"), T макросы устарели в 2000 году с появлением Layer for Unicode, и сегодня наши инструменты не могут создавать исполняемые файлы для версий Windows (9x), на которые нацелены эти макросы. Я так понимаю, это устаревшая кодовая база. Но когда ваша задача - очистить его, упоминание T макросов как удобных абсурдно и очень контрпродуктивно.   -  person Cheers and hth. - Alf    schedule 31.08.2017
comment
Если вы выберете узкие символы, тогда все, что вам нужно, чтобы сломать вашу программу, - это один сотрудник с нелатинским именем, и вы столкнетесь с проблемами кодирования для пользователя и следующих каталогов.   -  person Richard Critten    schedule 31.08.2017
comment
utf8everywhere.org   -  person Artemy Vysotsky    schedule 31.08.2017
comment
@BTownTKD; Ваше утверждение, что Windows предоставляет альтернативы узким символам почти для всех API, основано на полном незнании. Узкие функции выполняют преобразование в / из Windows ANSI, что (1) зависит от системы и (2) не может представлять, например, все пути файловой системы. Кроме того, многие API, особенно новые, не имеют оболочки ANSI.   -  person Cheers and hth. - Alf    schedule 31.08.2017
comment
@BTownTKD Я вижу общую тенденцию новых API-интерфейсов предоставлять только интерфейс с широкими символами.   -  person zett42    schedule 31.08.2017
comment
Такие вещи, как bstr_t, вам понадобятся, когда вы взаимодействуете с COM, а Windows предоставляет различные функции для их создания. В другом месте вы должны просто использовать std :: wstring и wchar_t, если вы пишете исключительно для Windows. Это легче.   -  person Robinson    schedule 31.08.2017


Ответы (2)


Если мы говорим о Windows, то я бы использовал std :: wstring (потому что нам часто нужны классные строковые функции) или wchar_t *, если вы просто передаете строки.

Примечание. Microsoft рекомендует здесь: Работа со строками

Windows изначально поддерживает строки Unicode для элементов пользовательского интерфейса, имен файлов и т. Д. Юникод является предпочтительной кодировкой символов, поскольку он поддерживает все наборы символов и языки. Windows представляет символы Unicode с использованием кодировки UTF-16, в которой каждый символ кодируется как 16-битное значение. Символы UTF-16 называются широкими символами, чтобы отличать их от 8-битных символов ANSI. Компилятор Visual C ++ поддерживает встроенный тип данных wchar_t для широких символов.

Также:

Когда Microsoft представила поддержку Unicode в Windows, она упростила переход, предоставив два параллельных набора API-интерфейсов: один для строк ANSI, а другой - для строк Unicode. [...] Внутренне версия ANSI переводит строку в Unicode.

Также:

Новые приложения всегда должны вызывать версии Unicode. Многие языки мира требуют Unicode. Если вы используете строки ANSI, локализовать приложение будет невозможно. Версии ANSI также менее эффективны, поскольку операционная система должна преобразовывать строки ANSI в Unicode во время выполнения. [...] Большинство новых API в Windows имеют только версию Unicode, без соответствующей версии ANSI.

person Simon Mourier    schedule 31.08.2017
comment
потому что нам часто нужны классные строковые функции ... можно немного доработать. Почему бы вместо этого не использовать CString, MFC использует его везде? Не то чтобы я бы рекомендовал это делать ;-) - person zett42; 31.08.2017
comment
@ zett42 - 10 или 20 лет назад (да, я такой старый :-), я бы тоже порекомендовал это, но сегодня существует так много примеров / кодов / открытого исходного кода / и т. д. используя std ::, а также к нему привыкло так много людей, что я чувствую себя хорошо с std ::, однако я также считаю, что CString также отлично подходит, если вы убедитесь, что никто не вводит std :: из-за лени ... - person Simon Mourier; 31.08.2017

По-разному.

При программировании для Windows я рекомендую использовать std::wstring как минимум для:

  • Ресурсы (строки, диалоги и т. Д.)
  • Доступ к файловой системе (Windows допускает использование символов, отличных от ASCII, в именах файлов и каталогов (включая все «неправильные виды апострофов», кстати), их невозможно открыть с помощью ANSI API)
  • COM (BSTR - это всегда широкий символ)
  • Другие пользовательские интерфейсы (буфер обмена, отчеты об ошибках системы и т. Д.)

Однако проще обрабатывать внутренние файлы данных ASCII и данные в кодировке UTF-8, используя односимвольные строки. Это быстро, эффективно и просто.

Также могут быть другие аспекты, не упомянутые в вопросе, такие как используемые базы данных или API, файлы ввода / вывода и т. Д. И их кодировки - все они играют роль при выборе наилучших структур данных для работы.

«UTF-8 везде» - в целом разумная идея. Но есть 0 Windows API, который принимает UTF-8. Даже std::experimental::filesystem API использует std::wstring в Windows и std::string в POSIX.

person rustyx    schedule 31.08.2017