2-е обновление: Я нашел очень простое решение , что на самом деле это не такая сложная проблема, всего один день после запроса.Но люди кажутся недалекими, так что уже есть три близких голоса:
Дубликат "Как использовать символы Юникода в командной строке Windows?"(1x) :
Очевидно, нет, что было разъяснено в комментариях.Речь идет не об инструменте командной строки Windows, которым я не пользуюсь.
Непонятно, о чем вы спрашиваете (1x) :
Тогда вы должны страдать от функционального аналфавитизма .Я не могу быть более конкретным, когда спрашиваю, например: « Есть ли простой способ определить, является ли символ в std :: string неконечной частью символа UTF-8? » (помечены жирным шрифтом для лучшей видимости, действительно) и утверждают, что этого будет достаточно, чтобы ответить на вопрос (и даже объяснить, почему).Серьезно, есть даже картинки, чтобы показать проблему.Кроме того, мой собственный существующий ответ должен прояснить это еще больше.Ваши собственные недостатки недостаточны, чтобы объявить что-то слишком сложным для понимания.
Слишком широкий (1x) ("Пожалуйста, отредактируйте вопрос, чтобы ограничить его конкретнымпроблема с достаточным количеством деталей для определения адекватного ответа [...] "):
Это должно быть еще одна проблема с функциональным аналфавитизмом.Я четко заявил, что достаточно одного способа решения проблемы (который я уже нашел) достаточно.Вы можете определить адекватный ответ следующим образом: Взгляните на принятый ответ моего собственного.В качестве альтернативы, используйте свой мозг, чтобы интерпретировать мои четко определенные слова, если вы в состоянии, что, к сожалению, кажется, несколько человек на этой платформе.
Однако есть реальная причина закрытьэтот вопрос: он уже решен.Но такой возможности для закрытого голосования нет.Итак, ясно, Stack Exchange поддерживает, что могут быть найдены альтернативные решения.Поскольку я любопытный человек, меня также интересуют альтернативные способы решения этой проблемы.Если ваш недостаток интеллекта не справляется с пониманием, в чем заключается проблема и что она весьма актуальна в определенных средах (например, таких, которые используют Windows, C ++ в Eclipse CDT, UTF-8, но no Visual Studioи no Windows Console), тогда вы можете просто уйти, не стоя на пути других людей, чтобы удовлетворить их любопытство.Спасибо!
1-е обновление: Я использовал app.exe > out.txt 2>&1
, который генерирует файл без этих проблем форматирования.Таким образом, проблема в том, что обычно std :: cout выполняет это разбиение, но базовый элемент управления (который получает последовательность символов) должен обрабатывать правильную повторную сборку?(К сожалению, в Windows, похоже, ничего не происходит, кроме потоков файлов. Поэтому мне все еще нужно обойти это. Желательно без предварительной записи файлов и отображения их содержимого - что, конечно, работает.)
Вкл.В системе, которую я использую (Windows 7; MinGW-w64 (GCC 8.1 для Windows)), есть ошибка с std::cout
, так что строки в кодировке UTF-8 выводятся на печать до их повторной сборки, даже если они были разобраны внутриstd::cout
, передав большую строку.Следующий код объясняет, как ошибка ведет себя.Обратите внимание, что, однако, ошибочные отображения выглядят случайными, т. Е. Способ, которым std::cout
разделяет (равно) std::string
объекты, не эквивалентен для каждого выполнения программы.Но проблемы постоянно появляются при индексах, кратных 1024, и вот как я сделал вывод о таком поведении.
#include <iostream>
#include <sstream>
void myFaultyOutput();
void simulatedFaultyBehavior();
int main()
{
myFaultyOutput();
//simulatedFaultyBehavior();
}
void myFaultyOutput() {
std::stringstream ss; // Note that ss is built correctly (which could be shown by saving ss.str() to a file).
ss << "...";
for (int i = 0; i < 20; i++) {
for (int j = 0; j < 341; j++)
ss << u8"\u301A";
ss << "\n..";
}
std::cout << ss.str() << std::endl; // Problem occurs here, with cout.
// Note that converting ss.str() to UTF-16 std::wstring and using std::wcout results in std::wcout not
// displaying anything, not even ASCII characters in the future (until restarting the application).
}
// To display the problem on well-behaved systems ; just imagine the output would not contain newlines, while the faulty formatted characters remain.
void simulatedFaultyBehavior() {
std::stringstream ss;
int amount = 2000;
for (int j = 0; j < amount; j++)
ss << u8"\u301A";
std::string s = ss.str();
std::cout << "s.length(): " << s.length() << std::endl; // amount * 3
while (s.length() > 1024) {
std::cout << s.substr(0, 1024) << std::endl;
s = s.substr(1024);
}
std::cout << s << std::endl << std::flush;
}
Чтобы обойти это поведение, я бы хотел разделить большие строки (которые я получаю как таковые из API) вручную на части длиной менее 1024 символов (и затем вызывать std :: cout отдельно для каждой из них).Но я не знаю, какие символы на самом деле являются просто бесконечной частью символа UTF-8, и встроенные преобразователи Unicode также кажутся ненадежными (возможно, также зависящими от системы?). Существует ли простой способ определить, является ли символ в std::string
неконечной частью символа UTF-8? Следующая цитата объясняет, почему было бы достаточно ответа на этот вопрос.
Символ UTF-8 может, например, состоять из трех символов.Так что если кто-то разбивает строку на две части, он должен держать эти три символа вместе.В противном случае необходимо делать то, что существующие элементы управления графическим интерфейсом явно не в состоянии сделать последовательно.Например, повторная сборка символов UTF-8, которые были разбиты на части.
Лучшие идеи для обхода проблемы (кроме «Не используйте Windows» / «Не используйте UTF-8»)"/" Не используйте cout ", конечно) также приветствуются.
Обратите внимание, что этот вопрос не относится к консоли Windows (я не использую его - все отображается в Eclise и, возможно, в wxWidgetsЭлементы пользовательского интерфейса, которые правильно отображают UTF-8).Это также не связано с MSVC (как я уже упоминал, я использую MinGW-компилятор).В коде также упоминается, что использование std :: wcout с UTF-16 вообще не работает (из-за другой MinGW ошибка Eclipse). Ошибка является результатом того, что элементы управления пользовательского интерфейса не могут обрабатывать действия std::cout
(которые могут быть преднамеренными или нет). Кроме того, все обычно работает нормально, за исключением этих символов UTF-8.которые были разделены на разные символы (например, \ u301A на \ u0003 + \ u001A) с индексами, кратными 1024 (и только случайным образом).Такое поведение уже подразумевает, что большинство предположений комментаторов являются ложными.Пожалуйста, внимательно рассмотрите код, особенно его комментарии, а не спешите с выводами.
Чтобы прояснить проблему с отображением при вызове myFaultyOutput()
: