Длина C ++ std :: string в байтах

У меня возникли проблемы с определением точной семантики std::string.length(). В документации прямо указано, что length() возвращает количество символов в строке и не количество байтов. Мне было интересно, в каких случаях это действительно имеет значение.

В частности, относится ли это только к экземплярам std::basic_string<> без символов, или я также могу столкнуться с проблемами при хранении строк UTF-8 с многобайтовыми символами? Допускает ли стандарт length() поддержку UTF8?


person ComicSansMS    schedule 12.10.2011    source источник
comment
есть wstring для UTF, и он понимает, что длина возвращает количество символов, поскольку размер символа может варьироваться.   -  person AndersK    schedule 12.10.2011
comment
@AndersK .: Нет, wchar_t имеет фиксированный размер, как и любой другой тип. Это не может измениться волшебным образом.   -  person Lightness Races in Orbit    schedule 12.10.2011
comment
Также проверьте эту прекрасную ветку о std::string и std::wstring и кое-что о Юникоде: stackoverflow.com / questions / 402283 / stdwstring-vs-stdstring.   -  person wkl    schedule 12.10.2011
comment
@AndersK .: wstring не имеет ничего общего с UTF. Возможно, вы думали о u16string или u32string?   -  person Kerrek SB    schedule 12.10.2011


Ответы (4)


Конечно, при работе с экземплярами std::basic_string<>, отличными от char, длина может не равняться количеству байтов. Это особенно очевидно с std::wstring:

std::wstring ws = L"hi";
cout << ws.length();     // <-- 2, not 4

Но std::string составляет около char символов; Для std::string не существует такой вещи, как многобайтовые символы, независимо от того, набили ли вы их на высоком уровне или нет. Итак, std::string.length() - это всегда количество байтов, представленных строкой. Обратите внимание, что если вы втисываете многобайтовые «символы» в std::string, тогда ваше определение «символа» внезапно начинает расходиться с определением контейнера и стандарта.

person Lightness Races in Orbit    schedule 12.10.2011
comment
В этом есть смысл. Меня просто смутила формулировка в документации здесь. Спасибо, что прояснили ситуацию. - person ComicSansMS; 12.10.2011
comment
@ComicSansMS: Не проблема :) - person Lightness Races in Orbit; 12.10.2011
comment
Но std::string - это около char символов, поэтому определение символа в C ++ - это элемент некоторого строкового типа, а не то, что видит человек, закодированный или закодированный каким-то образом. Это звучит правдоподобно, но может ли кто-нибудь процитировать главы и стихи по этому поводу? - person Adrian Ratnapala; 08.01.2012
comment
@AdrianRatnapala: Дело не в том, что стандарт говорит, что он не заботится о кодировках, и больше об этом, не говоря, что это так. Тем не менее, 2.3/1 может представлять интерес - он определяет базовый набор символов. И 2.3/3 говорит: The execution character set and the execution wide-character set are implementation-defined supersets of the basic execution character set and the basic execution wide-character set, respectively. The values of the members of the execution character sets and the sets of additional members are locale-specific. - person Lightness Races in Orbit; 08.01.2012
comment
Ну, я думаю, это то, что я получаю, когда прошу главу и стих. - person Adrian Ratnapala; 08.01.2012
comment
@AdrianRatnapala: Да, когда вы просите главу и стих, вы получаете главу и стих. Чем еще я могу вам помочь? :) - person Lightness Races in Orbit; 08.01.2012

Если мы говорим конкретно о std::string, то length() действительно возвращает количество байтов.

Это потому, что std::string - это basic_string из char, а стандарт C ++ определяет размер одного char как ровно один байт.

Обратите внимание, что в стандарте не указано, сколько битов в байте, но это совсем другая история, и вам, вероятно, все равно.

РЕДАКТИРОВАТЬ: Стандарт действительно говорит, что реализация должна предоставлять определение для CHAR_BIT, которое говорит, сколько битов в байте.

Кстати, если вы пойдете по дороге, где вам все равно, сколько бит в байте, вы можете прочитать это.

person John Dibling    schedule 12.10.2011
comment
В самом деле, байт не обязательно является синонимом октета. - person Lightness Races in Orbit; 12.10.2011
comment
Стандарт действительно определяет CHAR_BIT, количество бит в байте. - person Mike Seymour; 12.10.2011
comment
@Mike: Верно, но в Стандарте не указано, для чего это определено. Когда я сказал, что не говорит, сколько бит в байте, я имел в виду в точном, однозначном смысле. Но я уточню свой пост с правкой, спасибо, что указали на это. - person John Dibling; 12.10.2011

std::string - это std::basic_string<char>, поэтому s.length() * sizeof(char) = byte length. Кроме того, std::string ничего не знает о UTF-8, поэтому вы получите размер байта, даже если это не совсем то, что вам нужно.

Если у вас есть данные UTF-8 в std::string, вам нужно будет использовать что-то еще, например ICU чтобы получить "настоящую" длину.

person NuSkooler    schedule 12.10.2011

cplusplus.com - это не «документация» для std::string, это некачественный сайт, полный некачественной информации. Стандарт C ++ определяет это очень четко:

  • # P2 #
    # P3 #
  • # P4 #
    # P5 # # P6 #
person Jonathan Wakely    schedule 28.05.2013