string
? wstring
? std::string
basic_string
шаблонные на char
, и std::wstring
на wchar_t
.
char
по сравнению с [1 110] char
, как предполагается, содержит символ, обычно 8-разрядный символ. wchar_t
, как предполагается, содержит широкий символ, и затем, вещи становятся хитрыми:
На Linux, wchar_t
4 байта, в то время как в Windows, это - 2 байта.
проблема состоит в том, что ни char
, ни wchar_t
непосредственно связывается с unicode.
Позволяют нам взять ОС Linux: Моя система Ubuntu уже unicode знающая. Когда я работаю с символьной строкой, она исходно кодируется в [1 150] UTF-8 (т.е. строка Unicode символов). Следующий код:
#include
#include
int main(int argc, char* argv[])
{
const char text[] = "olé" ;
std::cout << "sizeof(char) : " << sizeof(char) << std::endl ;
std::cout << "text : " << text << std::endl ;
std::cout << "sizeof(text) : " << sizeof(text) << std::endl ;
std::cout << "strlen(text) : " << strlen(text) << std::endl ;
std::cout << "text(ordinals) :" ;
for(size_t i = 0, iMax = strlen(text); i < iMax; ++i)
{
std::cout << " " << static_cast(
static_cast(text[i])
);
}
std::cout << std::endl << std::endl ;
// - - -
const wchar_t wtext[] = L"olé" ;
std::cout << "sizeof(wchar_t) : " << sizeof(wchar_t) << std::endl ;
//std::cout << "wtext : " << wtext << std::endl ; <- error
std::cout << "wtext : UNABLE TO CONVERT NATIVELY." << std::endl ;
std::wcout << L"wtext : " << wtext << std::endl;
std::cout << "sizeof(wtext) : " << sizeof(wtext) << std::endl ;
std::cout << "wcslen(wtext) : " << wcslen(wtext) << std::endl ;
std::cout << "wtext(ordinals) :" ;
for(size_t i = 0, iMax = wcslen(wtext); i < iMax; ++i)
{
std::cout << " " << static_cast(
static_cast(wtext[i])
);
}
std::cout << std::endl << std::endl ;
return 0;
}
выводы следующий текст:
sizeof(char) : 1
text : olé
sizeof(text) : 5
strlen(text) : 4
text(ordinals) : 111 108 195 169
sizeof(wchar_t) : 4
wtext : UNABLE TO CONVERT NATIVELY.
wtext : ol�
sizeof(wtext) : 16
wcslen(wtext) : 3
wtext(ordinals) : 111 108 233
Вы будете видеть, что "olГ©" текст в [1 116] действительно создается четырьмя символами: 110, 108, 195 и 169 (не подсчет конечного нуля). (Я позволю Вам учиться эти wchar_t
код как осуществление)
Так, при работе с char
на Linux, необходимо обычно заканчивать тем, что использовали Unicode, даже не зная это. И как [1 119] работы с [1 120], таким образом std::string
уже unicode-готово.
Примечание, что std::string
, как API струны до, будет полагать, что строка "olГ©" имеет 4 символа, не три. Таким образом, необходимо быть осторожными при усечении/игре с unicode символами, потому что некоторая комбинация символов запрещается в UTF-8.
В Windows, это несколько отличается. Win32 должен был поддержать много приложения, работающего с [1 123] и на различном наборы символов / кодовые страницы произведенный во всем мире перед появлением Unicode.
, Таким образом, их решением было интересное: Если приложение работает с [1 124], то символьные строки закодированы/распечатаны/показаны на маркировках GUI с помощью локального набора символов/кодовой страницы на машине. Например, "olГ©" был бы "olГ©" в локализованном французами Windows, но будет чем-то другим в локализованном кириллицей Windows ("olР№", если Вы используете Windows 1251 ). Таким образом, "исторические приложения" будут обычно все еще работать тот же старый путь.
Для основанных на Unicode приложений, использование Windows wchar_t
, который 2 байта шириной, и кодируется в [1 154] UTF-16, который является Unicode, закодированным на 2-байтовых символах (или по крайней мере, главным образом совместимый UCS-2, который является почти тем же самым IIRC).
Приложения с помощью [1 126] сказаны "многобайтовые" (потому что каждый глиф состоит из одного или нескольких char
с, в то время как приложения с помощью [1 128] сказаны "widechar" (потому что каждый глиф состоит из один или два wchar_t
. См. MultiByteToWideChar и API WideCharToMultiByte Win32 преобразования для большего количества информации
Таким образом, если Вы работаете над Windows, Вы плохо хотите использовать wchar_t
(если Вы не используете платформу, скрывающую это, как [1 157] GTK + или QT...). Факт - то, что негласно, работы Windows с [1 131] строки, поэтому даже историческим приложениям преобразуют их char
строки в [1 133] при использовании API как [1 134] (низкоуровневая API-функция для установки маркирования на Win32 GUI).
UTF-32 составляет 4 байта на символы, таким образом, существует не очень для добавления, если только, что текст UTF-8 и текст UTF-16 будут всегда использовать меньше или тот же объем памяти, чем текст UTF-32 (и обычно меньше).
, Если существует проблема памяти, то необходимо знать, чем для большинства западных языков, текст UTF-8 будет использовать меньше памяти, чем тот же UTF-16 один.
однако, для других языков (китайский язык, японский язык, и т.д.), используемая память будет или тем же, или немного больше для UTF-8, чем для UTF-16.
, В целом, UTF-16 будет главным образом использовать 2 и иногда 4 байта на символы (если Вы не будете иметь дело с некоторыми тайными глифами языка (Klingon? Волшебный?), в то время как UTF-8 потратит от 1 до 4 байтов.
Видят http://en.wikipedia.org/wiki/UTF-8#Compared_to_UTF-16 для большего количества информации
, Когда я должен использовать станд.:: wstring по станд.:: строка?
На Linux? Почти никогда (В§).
В Windows? Почти всегда (В§).
На межплатформенном коде? Зависит от Вашего инструментария...
(В§): если Вы не используете инструментарий/платформу, говорящий иначе
, Может std::string
содержать весь набор символов ASCII включая специальные символы?
Уведомление: std::string
подходит для содержания 'двоичного' буфера, где std::wstring
не!
На Linux? Да.
В Windows? Только специальные символы, доступные для текущей локали пользователя Windows.
Редактирование (После комментария от [1 160] Johann Gerell ): std::string
будет достаточно для обработки всего char
- базирующиеся строки (каждый char
являющийся числом от 0 до 255). Но:
char
с НЕ являются ASCII. char
от 0 до 127 будет сохранен правильно char
от 128 до 255, будет иметь значение в зависимости от Вашего кодирования (unicode, non-unicode, и т.д.), но оно будет в состоянии содержать все глифы Unicode, пока они кодируются в UTF-8. std::wstring
поддерживаются почти всеми популярными компиляторами C++?
Главным образом, за исключением GCC основывал компиляторы, которые портированы к Windows.
Это работает над моим g ++ 4.3.2 (в соответствии с Linux), и я использовал API Unicode на Win32 начиная с Visual C++ 6.
, Что такое точно широкий символ?
На C/C++, это - тип символов, записанный wchar_t
, который больше, чем простое char
тип символов. Это, как предполагается, используется для вставления символов, индексы которых (как глифы Unicode) больше, чем 255 (или 127, завися...).
Это пример проблемы, когда «я знаю, я буду использовать регулярные выражения!» это неправильное решение. Вы можете использовать регулярное выражение, чтобы проверить, что ваш формат ввода - цифра-цифра-двоеточие-цифра-цифра, а затем использовать логику программирования, чтобы убедиться, что значения находятся в ожидаемом диапазоне. Например:
/(\d\d?):(\d\d)/
if ($1 >= 1 && $1 <= 12 && $2 < 60) {
// result is valid 12-hour time
}
Это намного легче читать и понимать, чем некоторые примеры обфусцированных регулярных выражений, которые вы видите в других ответах здесь.
Вот так: ((?: 1 [0-2] | 0 \ d) \: (?: [0-5] \ d))
, если вы хотите, чтобы в начале часа начинался 0, ((?: 1 [0-2] | \ d) \: (?: [0-5 ] \ d))
, если вы этого не сделаете, и ((?: 1 [0-2] | 0? \ d) \: (?: [0-5] \ d))
если тебе все равно.
почему регулярное выражение? это можно сделать с помощью простой проверки целых чисел
$str = "12:74";
list($h , $m ) = explode(":",$str);
if ( ($h <=12 && $h >=0 ) && ($m <=59 && $m >=0) ) {
print "Time Ok.";
}else{
print "Time not ok";
}
Я считаю, что вышеперечисленное не работает, по крайней мере, одним способом, особенно в отношении таких строк, как «13:00» (в этом случае Кейт соответствует «3:00»).
Это должно решить эту проблему, а также другие подняты.
([01][0-2]|(?<!1)[0-9]):([0-5][0-9])
Думаю, я разобрался. Это может быть ошибка в коде конструктора, или, возможно, я пропустил какой-то шаг.
Я думаю, что в коде конструктора, в методе InitializeComponent (), предполагается добавить:
this.Installers.AddRange(new System.Configuration.Install.Installer[] {this.serviceProcessInstaller1, this.serviceInstaller1});
Этого не было, поэтому я добавил это в конструктор ProjectInstaller:
Installers.Add(serviceInstaller1);
Installers.Add(serviceProcessInstaller1);
Теперь при установке он отображается как служба в Управлении компьютером.
59(0?\d|1[0-2]):([0-5]\d)
Это будет соответствовать всему с 0:00 до 12:59. Это, кстати, 13 часов. Если вы не хотите сопоставить 0:00 - 0:59, попробуйте вместо этого:
([1-9]|1[0-2]):([0-5]\d)
Вы можете использовать этот:
/((?:1[0-2])|(?:0?[0-9])):([0-5][0-9]) ?([ap]m)/
/1 => hour
/2 => minute
/3 => am/pm
^(00|0[0-9]|1[012]):[0-5][0-9] ?((a|p)m|(A|P)M)$
^
- Соответствует началу строки.
(00 | 0 [0-9] | 1 [012])
- любое двузначное число вверх до 12. Требуется две цифры.
:
- Соответствует двоеточию
[0-5] [0-9]
- соответствие любому двузначному числу от 00 до 59.
?
- соответствие пробелу ноль или один раз.
((a | p) m | (A | P) M)
- Соответствует am или pm, без учета регистра.
$
- Соответствует концу строки.