Каковы наиболее используемые строковые типы в C ++ и как конвертировать между ними?
-
09-09-2019 - |
Вопрос
ИЛИ Как не убить себя или кого-то в следующий раз, когда компилятор C ++ выкрутит вам руку для преобразования между 2 произвольными строковыми типами просто для того, чтобы позабавить вас?
Мне трудно кодировать на C ++, так как я привык к VB6, C #, Ruby для операций со строками.Но теперь я потратил более 30 минут, пытаясь зарегистрировать строку, содержащую 2 идентификатора guid и строку, в окне отладки...и легче не становится
И я уже встретил RPC_WSTR
, std::wstring
и LPCWSTR
Существуют ли простые (или какие-либо еще) правила для определения конверсий между ними?Или это приходит только после многих лет пыток?
По сути, я ищу наиболее часто используемые строковые типы как в стандартных API, так и в библиотеках MS-specific / Visual C ++ ;Что делать в следующий раз, я вижу
Error 8 error C2664: 'OutputDebugStringW' : cannot convert parameter 1 from 'std::wstring' to 'LPCWSTR'
Обновить:Я исправил ошибку компиляции ^^^^.Я ищу более глобальный ответ, а не решение конкретной проблемы, которую я перечислил в качестве примера.
Решение
Существует два встроенных типа строк:
- Строки C ++ используют класс std::string (std::wstring для широких символов)
- Строки в стиле C - это указатели const char на const char*) (или
const wchar_t*
)
И то, и другое может быть использовано в коде C ++.Большинство API, включая Windows, написаны на C, и поэтому они используют указатели char, а не класс std::string.
Далее Microsoft скрывает эти указатели за рядом макросов.
LPCWSTR - это Длинный указатель на строку постоянной ширины, или, другими словами, a const wchar_t*
.
LPSTR - это Длинный указатель на строку, или, другими словами, a char*
(не const).
У них есть еще несколько вариантов, но о них должно быть довольно легко догадаться, как только вы познакомитесь с первыми несколькими.У них также есть варианты * TSTR, где T используется для указания того, что это могут быть либо обычные, либо широкие символы, в зависимости от того, включен ли UNICODE в проекте.LPCTSTR преобразуется в LPCWSTR, если определен UNICODE, и LPCSTR в противном случае.
Так что на самом деле, при работе со строками вам просто нужно знать два типа, которые я перечислил вверху.Остальные - это просто макросы для различных вариантов версии указателя символа.
Преобразование указателя char в строку выполняется просто:
const char* cstr = "hello world";
std::string cppstr = cstr;
И другой путь не намного сложнее:
std::string cppstr("hello world");
const char* cstr = cppstr.c_str();
Это, std::string
принимает строку в стиле C в качестве аргумента в конструкторе.И в нем есть c_str()
функция-член, которая возвращает строку в стиле C.
Некоторые часто используемые библиотеки определяют свои собственные строковые типы, и в этих случаях вам придется проверить документацию о том, как они взаимодействуют с "правильными" строковыми классами.
Обычно вы должны предпочесть C ++ std::string
класс, поскольку, в отличие от указателей char, они веди себя прилично как струны.Например:
std:string a = "hello ";
std:string b = "world";
std:string c = a + b; // c now contains "hello world"
const char* a = "hello ";
const char* b = "world";
const char* c = a + b; // error, you can't add two pointers
std:string a = "hello worl";
char b = 'd';
std:string c = a + b; // c now contains "hello world"
const char* a = "hello worl";
char b = 'd';
const char* c = a + b; // Doesn't cause an error, but won't do what you expect either. the char 'd' is converted to an int, and added to the pointer `a`. You're doing pointer arithmetic rather than string manipulation.
Другие советы
Вот такой Статья это охватывает то, что вам нужно в основном для CString
OutputDebugStringW (myString.c_str ());
Добро пожаловать в C++ ;-)
Вы можете просто создать функцию-оболочку, которая принимает std::string
.Затем в функции извлеките строку в стиле c и передайте в OutputDebugStringW
.
std::wstring
и std::string
это просто псевдонимы для std::basic_string<wchar_t>
и std::basic_string<char>
.
У обоих есть .c_str()
-метод, который возвращает обычный указатель на C-строку (LPCWSTR
и т.д.) и конструктор, который принимает C-строку.
Возможно, вы захотите взглянуть на CStdString ( Строка CSTD ).Это кроссплатформенная стандартная реализация C ++ CString, которая довольно легко преобразуется в большинство других строковых типов.Устраняет почти все головные боли, связанные со строками, и это всего лишь один заголовочный файл.