Не удается найти wchar_t, который присутствует в std :: wstring

Я играл с std::wstring а также std::wfstream, когда я столкнулся со странным поведением. А именно, похоже, что std::basic_string<wchar_t>::find не может найти определенные символы. Рассмотрим следующий код:

int main()
{
std::wifstream input("input.txt");
std::wofstream output("output.txt");

if(!(input && output)){
std::cerr << "file(s) not opened";
return -1;
}

std::wstring buf;
std::getline(input, buf);

output << buf;

std::cout << buf.find(L'ć');
}

Здесь я просто читаю первую строку input файл и запись его в output файл. Перед запуском программы содержимое первого файла aąbcćd и выходной файл пуст. После выполнения кода входной файл успешно копируется в выходной файл.

Что меня удивляет, так это то, что я пытался найти ć письмо в buf и столкнулся с упомянутым странным поведением. После выполнения программы я подтвердил, что выходной файл содержит точно aąbcćdкоторый, очевидно, содержит упомянутый символ ć,

Тем не менее, линия std::cout << buf.find(L'ć') вел себя не так, как ожидалось. Я не ожидал получить вывод 4, учитывая расположение памяти std::wstringно я тоже определенно не ожидал получить std::string::npos. Стоит отметить, что поиск обычных символов ASCII с помощью этого метода завершается успешно.

Подводя итог, упомянутый код правильно копирует первую строку входного файла в выходной файл, но ему не удается найти символ в строке (возвращающий npos), который отвечает за хранение данных, которые должны быть скопированы. Почему это так? Что вызывает find потерпеть неудачу здесь?

Примечание: оба файла имеют кодировку UTF-8 в Windows.

0

Решение

к несчастью wchar_t это не UTF-8, его UTF-16 (в Windows), и при чтении файла UTF-8 не происходит никакого волшебного преобразования. Если вы отладите свою программу, вы увидите поврежденные символы в вашем buf переменная.

Вам либо нужно прочитать вашу строку как std::string затем конвертировать из UTF-8 в whar_t или работать в UTF-8 и конвертировать вашу литеральную строку из whcar_t в std::string из UTF-8 символов.

Если вы используете недавний компилятор, вы можете использовать следующее для создания строкового литерала UTF-8:

u8"ć"

Следующее должно работать:

int main()
{
std::ifstream input("input.txt");
std::ofstream output("output.txt");

if(!(input && output)){
std::cerr << "file(s) not opened";
return -1;
}

std::string buf;
std::getline(input, buf);

output << buf;

std::cout << buf.find(u8"ć");
}
1

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

Других решений пока нет …

По вопросам рекламы [email protected]