Как правильно работать с wstrings?

#c #visual-c #c 17 #wstring

#c #visual-c #c 17 #wstring

Вопрос:

Я изучаю wstrings, потому что хочу понимать UTF-8 для проекта. Я создал простую программу для тестирования операций с использованием wstrings:

 int main()
{
   std::wstring test;
   std::wstring test2;
   std::wstring test3;
   int n;

   getline(std::wcin, test);

   std::wcout << "n" << test;

   for (n = 0; n < test.size(); n  )
   {
      test[n]  = n * n;
      test2[n] = test[n];
   }
   std::wcout << test2 << "n";

   for (n = 0; n < test2.size(); n  )
   {
    test2[n] -= n * n;
    test3[n] = test[n];
   }
   std::wcout << test3 << "n";

  return 0;
}
  

Когда я его выполняю, я получаю эту ошибку: «строковый индекс вне диапазона»

Это мой первый «серьезный» проект на C , и я ценю любую помощь!

Комментарии:

1. обратите внимание, что std::wstrings и utf-8 вряд ли будут связаны, например, в Windows std::wstring закодировано utf-16

2. Действительно? На самом деле я немного запутался в этом. Я думал, что мне нужны wstrings, потому что по какой-то причине, когда я использовал std::string, символы в test2 и test3 не передавали часть символов Юникода от 0 до 255. Спасибо за информацию.

3. да, вы должны использовать std::u8string в c 20 или просто std::string раньше для хранения utf-8 en.cppreference.com/w/cpp/string/basic_string

4. @GuilhermeGaldino std::wstring использует wchar_t элементы, размер которых составляет 2 байта в Windows и 4 байта на других платформах. Итак, std::wstring кодируется UTF-16 в Windows и UTF-32 в других платформах. std::string использует char элементы, размер которых составляет 1 байт на всех платформах. До C 20 std::string может содержать строку в кодировке UTF-8. C 20 добавляет char8_t и std::u8string для этой цели вместо этого. Любая строка в кодировке UTF может обрабатывать весь Unicode. Но большинство функций Windows API предпочитают только локальные строки ANSI или UTF-16.

Ответ №1:

Ваша test2 строка пуста, поэтому, когда вы делаете:

 test2[n] = test[n];
  

вы индексируете в недопустимом местоположении, что вызывает неопределенное поведение. Это может привести к возникновению исключения.

Вместо этого вы можете сделать:

 test2.push_back(test[n]);
  

У вас та же проблема с test3 , которую вы можете исправить тем же способом.


В качестве альтернативы, прочитав в test , вы можете инициализировать test2 и test3 с соответствующим количеством элементов:

 getline(std::wcin, test);

std::wstring test2(test.size());
std::wstring test3(test.size());
  

и теперь вы можете индексировать в эти строки без каких-либо проблем.


Кроме того, для вашей проблемы вам даже не нужно выполнять индексацию в test2 . После внесения изменений test вы можете просто назначить его следующим образом:

 for (n = 0; n < test.size(); n  )
{
      test[n]  = n * n;
}
std::wstring test2 = test;
  

и аналогично для test3 .