#c #struct #wchar-t
#c #структура #wchar-t
Вопрос:
Я пытаюсь загрузить некоторые строки из базы данных в структуру, но я продолжаю сталкиваться со странной проблемой. Использование моей структуры данных,
struct datum {
wchar_t* name;
wchar_t* lore;
};
Я попробовал следующий фрагмент кода
datum thisDatum;
size_t len = 0;
wchar_t wBuffer[2048];
mbstowcs_s(amp;len, wBuffer, (const char*)sqlite3_column_text(pStmt, 1), 2048);
if (len) {
thisDatum.name = new wchar_t[len 1];
wcscpy_s(thisDatum.name, len 1, wBuffer);
} else thisDatum.name = 0;
mbstowcs_s(amp;len, wBuffer, (const char*)sqlite3_column_text(pStmt, 2), 2048);
if (len) {
thisDatum.lore = new wchar_t[len 1];
wcscpy_s(thisDatum.lore, len 1, wBuffer);
} else thisDatum.name = 0;
Однако при thisDatum.name
правильном копировании thisDatum.lore
всегда остается мусор, за исключением двух случаев. Если проект отлаживается, все в порядке, но это просто не вариант. Я также обнаружил, что переписывание данных структуры
struct datum {
wchar_t* lore;
wchar_t* name;
};
полностью устраняет проблему для thisDatum.lore
, но дает мне мусор для thisDatum.name
.
Комментарии:
1. Не то чтобы это имело значение, но в последнем
else
случае обнуляется неправильная переменная.2. Упс, спасибо. Это могло быть плохо.
3. Почему бы просто не использовать
std::wstring
вместоwchar_t*
?4. Разве вы не должны использовать
len
вместоlen 1
того, чтобы при вызовеwcscpy_s
?5. Кроме того,
mbstowcs_s
задает размер выходных данных, сохраненный вlen
, чтобы отразить включение терминатора. Нет необходимости в арифметике 1.
Ответ №1:
Попробуйте что-то более похожее на это:
struct datum {
wchar_t* name;
wchar_t* lore;
};
wchar_t* widen(const char *str)
{
wchar_t *wBuffer = NULL;
size_t len = strlen(str) 1;
size_t wlen = 0;
mbstowcs_s(amp;wlen, NULL, 0, str, len);
if (wlen)
{
wBuffer = new wchar_t[wlen];
mbstowcs_s(NULL, wBuffer, wlen, str, len);
}
return wBuffer;
}
datum thisDatum;
thisDatum.name = widen((const char*)sqlite3_column_text(pStmt, 1));
thisDatum.lore = widen((const char*)sqlite3_column_text(pStmt, 2));
...
delete[] thisDatum.name;
delete[] thisDatum.lore;
При этом я бы использовал std::wstring
вместо:
struct datum {
std::wstring name;
std::wstring lore;
};
#include <locale>
#include <codecvt>
std::wstring widen(const char *str)
{
std::wstring_convert< std::codecvt<wchar_t, char, std::mbstate_t> > conv;
return conv.from_bytes(str);
}
datum thisDatum;
thisDatum.name = widen((const char*)sqlite3_column_text(pStmt, 1));
thisDatum.lore = widen((const char*)sqlite3_column_text(pStmt, 2));
Комментарии:
1. 1 за то, что фактически предоставил C решение проблемы C