строка — манипуляции C ++ WCHAR

Я разрабатываю крошечное приложение Win32 на C ++.
Я изучал основы C ++ очень давно, поэтому теперь я полностью сбит с толку из-за символьных строк в C ++. Не было WCHAR или же TCHAR только char а также String,
После небольшого расследования я решил не использовать TCHAR,

Я думаю, что моя проблема очень проста, но я не могу найти четкого руководства по работе со строками в C ++. В последние несколько лет под влиянием PHP-кодирования я ожидал чего-то простого с манипуляциями со строками и ошибался!

Просто все, что мне нужно, это поместить новые данные в строку символов.

    WCHAR* cs = L"\0";
swprintf( cs, "NEW DATA" );

Это была моя первая попытка. При отладке моего приложения я исследовал, что swprintf помещает только первые 2 символа в мою переменную cs. Я решил свою проблему следующим образом:

    WCHAR cs[1000];
swprintf( cs, "NEW DATA" );

Но обычно этот трюк может не сработать, потому что в моем случае новые данные — это не постоянное значение, а другая переменная, которая потенциально может быть шире, чем 1000 символов. И мой код выглядит так:

    WCHAR cs[1000];
WCHAR* nd1;
WCHAR* nd2;
wcscpy(nd1, L"Some value");
wcscpy(nd2, L"Another value"); // Actually these vars stores the path for user selected folder
swprintf( cs, "The paths are %s and %s", nd1, nd2);

В этом случае существует вероятность, что общее число символов nd1 и nd2 может быть больше 1000 символов, поэтому критические данные будут потеряны.

Вопрос в том, как мне скопировать все данные, которые мне нужны, в строку WCHAR, объявленную таким образом. WCHAR* wchar_var; ничего не потеряв?

Постскриптум Поскольку я русский, вопрос может быть неясным. Позвольте мне рассказать об этом, и я постараюсь объяснить мою проблему более четко и сложно.

6

Решение

В современном программировании Windows нормально игнорировать TCHAR и вместо этого использовать wchar_t (WCHAR) и Unicode UTF-16.

(TCHAR Это модель прошлого, когда вы хотели иметь единую кодовую базу и создавать сборки ANSI / MBCS и Unicode, изменяя некоторые препроцессорные переключатели, такие как _UNICODE а также UNICODE.)

В любом случае, вы должны использовать C ++ и удобно классы строки упростить ваш код. Ты можешь использовать ATL::CString (что соответствует CStringW в сборках Unicode (по умолчанию с VS2005) или STL std::wstring,

С помощью CString, ты можешь сделать:

CString str1 = L"Some value";
CString str2 = L"Another value";
CString cs;
cs.Format(L"The paths are %s and %s", str1.GetString(), str2.GetString());

CString также обеспечивает надлежащие перегрузки operator+ объединить строки (чтобы вам не приходилось вычислять общую длину полученной строки, динамически выделять буфер для строки назначения или проверять существующий размер буфера, вызывать wcscpy, wcscatне забудьте освободить буфер и т. д.)

И вы можете просто передать экземпляры CString ожидающих API Win32 const wchar_t* (LPCWSTR/PCWSTR) параметры, так как CString предлагает оператор неявного преобразования const wchar_t*,

7

Другие решения

Когда вы используете WCHAR*, вы вызываете неопределенное поведение, потому что у вас есть указатель, но вы не указали на что-либо действительное. Вам необходимо выяснить, какова будет длина полученной строки, и динамически выделить место для этой строки. Например:

WCHAR* cs;
WCHAR* nd1;
WCHAR* nd2;

nd1 = new WCHAR[lstrlen(L"Some value") + 1]; // +1 for the null terminator
nd2 = new WCHAR[lstrlen(L"Another value") + 1];
cs = new WCHAR[lstrlen(L"The paths are  and ") + lstrlen(nd1) + lstrlen(nd2) + 1];

wcscpy(nd1, L"Some value");
wcscpy(nd2, L"Another value"); // Actually these vars stores the path for user selected folder
swprintf( cs, L"The paths are %s and %s", nd1, nd2);

delete[] nd1;
delete[] nd2;
delete[] cs;

Но это очень уродливо и подвержено ошибкам. Как уже отмечалось, вы должны использовать std::wstring вместо этого что-то вроде этого:

std::wstring cs;
std::wstring nd1;
std::wstring nd2;

nd1 = L"Some value";
nd2 = L"Another value";
cs = std::wstring(L"The paths are ") + nd1 + L" and " + nd2;
2

Предложить использовать ATL CStringW класс вместо сырья WCHARГораздо удобнее. CString является оберткой для динамически размещаемой C-строки Он будет управлять длиной строки & Распределите буфер памяти соответствующим образом после каждой операции, чтобы вам было все равно.

Типичное использование:

#include <atlstr.h>

CStringW s;
s.Format(L"The paths are %s and %s", L"Some value", L"Another value");
const WCHAR* wstr = s.GetString(); // To pass to some API that need WCHAR

или же

#include <atlstr.h>

CStringW s(L"The paths are ");
s += L"Some value";
s += L" and ";
s += L"Another value";
const WCHAR* wstr = s.GetString(); // To pass to some API that need WCHAR
1
По вопросам рекламы [email protected]