Wcout c что это
Перейти к содержимому

Wcout c что это

  • автор:

Wcout c что это

Здравствуйте. Я так понимаю, что если в моей системе локаль настроена правильно, то следующий код должен работать так, как я думаю: 1. Вывести кол-во символов в строке «Привет!», т.е. 7
2. Вывести строку «Привет!».
3. Считывать строки с стандартного потока и выводить их длинну.
А вот код и как он работает:
cat ./main.cpp
#include int main()
{
std::wstring s(L»Привет!»);
std::wcout while ( std::wcin >> s )
{
std::wcout } std::wcout std::wcout std::wcout std::wcout return 0;
} sy@localhost ~$ g++ main.cpp && ./a.out
7.
qwe
3
вап
wcin.eof()=1
wcin.good()=0
wcin.fail()=1
wcin.bad() =0 т.е. Русские буквы не вводятся и не выводятся. Где я не прав? Подскажите, пожалуйста.

Сообщения по теме [Сортировка по времени | RSS]

Если заменить wcin/wcout/wstring на cin/cout/string и убрать L в s(L»Привет!»), все будет работать.

>Если заменить wcin/wcout/wstring на cin/cout/string и убрать L в s(L»Привет!»), все будет
>работать.

Ага, только учитывая, что у меня юникод, в первом пункте я получу не кол-во букв, а кол-во байт, т.е 13.

Какбы не канает такое решение.

В самом начале следует установить локаль. Еще по ходу пьесы может потребоваться подергать всякие ios_base::imbue для потоков, ну там запятые вместо точек выводить для double 🙂

#include
#include

int main()
{
setlocale(LC_ALL, «»);

std::wstring ws(L»Уличная магия»);
std::wcout return 0;
}

>В самом начале следует установить локаль. Еще по ходу пьесы может потребоваться
>подергать всякие ios_base::imbue для потоков, ну там запятые вместо точек выводить
>для double 🙂

Да, так как Вы написали все работает. Правда, что-то я ничего не понял.
Локаль должна же быть установлена в соответствии с переменными окружения? Или нет?

>>В самом начале следует установить локаль. Еще по ходу пьесы может потребоваться
>>подергать всякие ios_base::imbue для потоков, ну там запятые вместо точек выводить
>>для double 🙂
>
>Да, так как Вы написали все работает. Правда, что-то я ничего не
>понял.
>Локаль должна же быть установлена в соответствии с переменными окружения? Или нет?
>

setlocale(LC_ALL,»»); — означает:

Specifies an implementation-defined native environment. This corresponds to the value of the associated environment variables, LC_* and LANG ; see the Base Definitions volume of IEEE Std 1003.1-2001, Chapter 7, Locale and the Base Definitions volume of IEEE Std 1003.1-2001, Chapter 8, Environment Variables.

http://www.opennet.ru/man.shtml?topic=setlocale&category=3&r.

По нашему: локаль в процессе устанавливается в соответствии с текущим окружением (определяемым переменными окружения), вместо дефолтовой «C».

>
>setlocale(LC_ALL,»»); — означает:
>
>По нашему: локаль в процессе устанавливается в соответствии с текущим окружением (определяемым
>переменными окружения), вместо дефолтовой «C».

Это C. А в С++ как локаль устанавливать?

>>
>>setlocale(LC_ALL,»»); — означает:
>>
>>По нашему: локаль в процессе устанавливается в соответствии с текущим окружением (определяемым
>>переменными окружения), вместо дефолтовой «C».
>
>Это C. А в С++ как локаль устанавливать?

#include

int main()
{
std::locale l(getenv(«LANG»));
std::locale::global(l);

.
}

Высказать мнение | Ответить | Правка | Наверх | Cообщить модератору


Архив | Удалить

Индекс форумов | Темы | Пред. тема | След. тема
Оцените тред (1=ужас, 5=супер)? [ Рекомендовать для помещения в FAQ]

Использование wcout

Wcout: Вывод непонятных символов
Всем доброго времени суток. Пишу прогу, которая вычленит из html-файла определенные тэги и выведет.

Cout и wcout. Русские буквы
Здравствуйте. При попытке считать из текстового файла, который содержит строку — "Привет!" — и.

wcout, wfstream в Code Blocks
Не пойму, почему компилятор не определяет wcout, wfstream. #include <iostream>, #include <fstream>.

Std::wcout не выводит сообщение
Здравствуйте. Вот в таком коде : int _tmain(int argc, _TCHAR* argv)

Вывод в консоль cout и wcout одновременно

Тебя где-то справшивали о том, как с этим жить? Вопрос был об устройстве вывода и причинах по которым файлы приобретают ориентацию. Твою блеяние мимо вообще. Ну и потом — твоя ссылка туфта, ибо http://eel.is/c++draft/iostream.objects.overview#6, а C library говорит:

After a stream is associated with a file, but before any operations are performed on the stream, the stream is without orientation. If a wide-character input or output function is applied to a stream without orientation, the stream becomes wide-oriented. Likewise, if a byte input or output operation is applied to a stream with orientation, the stream becomes byte-oriented. Thereafter, only the fwide() or freopen() functions can alter the orientation of a stream. Byte input/output functions shall not be applied to a wide-oriented stream and wide-character input/output functions shall not be applied to a byte-oriented stream. 

Слышал, only the fwide() or freopen() functions can alter the orientation of a stream, нет там ничего про способ полоумного анонима с лора.

pavlick ★★
( 31.05.21 08:18:57 MSK ) автор топика

Раз уж тему сделал, смежный вопрос к адекватным участникам: многие клавиши на клаве генерят эскейп последовательности (на уровне io потоков), заметил, что последовательности нестандартизированны вообще никак, нажатие F5 под VT даёт 4 символа, под иксовым ST 5 символов. Как в общих чертах нужно интерпретировать эти последоввательности (видимо терминфо?), может название функции, которой можно последовательность дать. Странно, почему в этой области не появилось никакого стандарта.

pavlick ★★
( 31.05.21 08:32:56 MSK ) автор топика
Ответ на: комментарий от pavlick 31.05.21 08:32:56 MSK

Странно, что ты ещё до сих пор не забанился.

LamerOk ★★★★★
( 31.05.21 09:51:16 MSK )

в теории «высокоуровневые средства упрощают написание кода»

anonymous
( 31.05.21 10:08:08 MSK )

Токсичная среда. Участников, от которых можно получить ценный совет можно по пальцам пересчитать. С остальными история про бисер. Ок, банюсь.

pavlick ★★
( 31.05.21 10:50:17 MSK ) автор топика

Не уверен, что верно понял вопрос, но выскажу мнение. К сожалению, wcout устарел после появления utf-8. В Linux терминалы либо понимают utf-8 и тогда надо использовать cout и string с utf-8, либо понимают только ASCII.

Если надо, чтобы программа работала ещё и в Windows, то там установленный по умолчанию растровый шрифт не умеет в юникод. Можно хитрить с настройками шрифта, и получить относительно нормальный вывод через wcout, но ввод останется кривой. Для себя я пришёл к выводу, что и в Windows надо использовать string с utf-8, а при вводе-выводе его транслировать в однобайтную текущую кодировку через MultiByteToWideChar, WideCharToMultiByte и GetConsoleCP. Возможно, в десятке что-то улучшилось, но мой подход и там работает.

ncurses используется в линуксовых терминалах, поэтому не ясно для чего там wcout. По идее, там тоже должен быть utf-8, а значит только cout. А локаль устанавливается, чтобы запятую для отделения десятичного знака использовать. Но тут могу ошибаться.

Kogrom ★
( 31.05.21 22:30:39 MSK )
Ответ на: комментарий от Kogrom 31.05.21 22:30:39 MSK

chcp 65001 же, utf-8 nls
Старые венды конечно в пролёте, да

mittorn ★★★★★
( 01.06.21 01:05:40 MSK )
Ответ на: комментарий от Kogrom 31.05.21 22:30:39 MSK

mittorn , Kogrom

и забыть о проблеме на всех Windows начиная с Windows XP.

fsb4000 ★★★★★
( 01.06.21 01:12:45 MSK )
Ответ на: комментарий от fsb4000 01.06.21 01:12:45 MSK
mittorn ★★★★★
( 01.06.21 08:40:26 MSK )
Ответ на: комментарий от Kogrom 31.05.21 22:30:39 MSK

К сожалению, wcout устарел после появления utf-8.

Он не устарел. Широкие символы — это абстракция над символом, которая может вместить любой символ целиком. Конечно и здесь есть грабли в виде, например, диакритических символов — в итоге на один символ уйдет более одного wchar_t, но всё равно — каждый wchar_t будет представлять полный code point.

В Linux терминалы либо понимают utf-8 и тогда надо использовать cout и string с utf-8, либо понимают только ASCII.

Это не так работает. В том то и дело — мне вообще не надо заморачиваться по поводу кодировки локали. Я просто читаю с stdin, а libc сама конвертируют в эту абстракцию wchar_t, без разницы что там koir-8, utf или windows 1251 ( в программе нужно установить локаль сначала std::locale::global(locale(«»)) ). Я не говорю, что всё надо делать через wchar_t, как вариант.

ncurses используется в линуксовых терминалах, поэтому не ясно для чего там wcout. По идее, там тоже должен быть utf-8, а значит только cout.

Ну логично исользовать массив с константного размера ячейками, когда мэпишь его на экран, а не массив массивов под переменный utf. Хотя и тут проблемы с теме же диакритическими символами. Вообще юникод пошёл по какому-то странному пути, много лучше было не позволять никаких комбинированнх символов, разное начертание — другая code point. 150К символов в юникоде, utf-8 может закодить грубо 2млрд, неужели нельзя было обойтись без комбинированных символов? А в качестве вишенки всучили ещё precomposed characters для разных вариантов написания одинакового. По-моему, что-то пошло не так.

anonymous
( 01.06.21 08:47:56 MSK )
Ответ на: комментарий от pavlick 31.05.21 08:32:56 MSK

Почему миксовать не получается? В общем хочется деталей для понимания.

Насколько я понимаю, это напрямую связано с наличием внутреннего состояния потоков. Например, если состояние многобайтное, то его нельзя или трудно интерпретировать как юникодное.

Ну если так, то я не могу после ncurses (которая широкая внутренне) печатного цикла использовать cout и мне нужно переоткрывать stdout как пишут в доках. Кто-нибудь не согласен?

ncurses может и не использовать стандартные потоки, либо сделать их копию и использовать её. Стандарт же говорит о потоках, а не файлах, на которые они указывают.

Как в общих чертах нужно интерпретировать эти последоввательности (видимо терминфо?), может название функции, которой можно последовательность дать.

База terminfo сопоставляет последовательности с операциями и наоборот. Есть какие-то стандарты (упоминаются в 1, 2), но вообще всё сложно.

xaizek ★★★★★
( 01.06.21 19:58:29 MSK )
Ответ на: комментарий от fsb4000 01.06.21 01:12:45 MSK

Мы обсуждаем разновидности костылей. Можно выбрать любые по вкусу. Более здоровым подходом будет использование mintty вместо консоли по умолчанию. Так делает git. Но тут придётся таскать с собой дополнительные 4 мегабайта.

Kogrom ★
( 01.06.21 21:22:14 MSK )
Ответ на: комментарий от anonymous 01.06.21 08:47:56 MSK

Широкие символы — это абстракция над символом, которая может вместить любой символ целиком.

Я согласен и был бы рад, если бы wchar_t победил. Но победил utf.

В теории. А на практике есть терминалы, которые будет выводить непонятно что, если использовать для символа больше одного байта. И не важно, wchar_t или utf-8 у нас будет. Другие будут ожидать, что wchar_t содержит 4 байта, а не 2. Поэтому в Linux остаётся выбирать адекватный терминал и пользоваться uft-8.

Думаю оно так, потому что создатели этой системы сами ей не пользуются. Но нас это устраивает. Иначе бы придумали какую-нибудь РУТФ-8, в которой русские буквы находятся среди первых 128 символов, и терминалы, которые это понимают.

А в качестве вишенки всучили ещё precomposed characters для разных вариантов написания одинакового.

Недавно ради интереса попробовал реализовать 64-битный растровый шрифт. В картинку 8 на 8 влез любой символ с клавиатуры. Размер png на 180 клеток вышел 2,9 килобайт. То есть можно ужать если не до 16 бит, то до 32 точно. Вот вам и кодировка в лоб без всяких комбинаций.

Были ещё такие штуки, как 16-сегментные индикаторы, с помощью которых можно было создать любую латинскую букву и почти все кириллические, кроме Ё, Ц, Щ (их тоже можно, но будет нечитаемо). Правда, это касается только заглавных букв. Но в 32 сегмента можно и маленькие вместить. Возможно, даже несколько бит на цвет останется.

Kogrom ★
( 01.06.21 21:59:59 MSK )
Ответ на: комментарий от xaizek 01.06.21 19:58:29 MSK

ncurses может и не использовать стандартные потоки, либо сделать их копию и использовать её.

Использует те же, проверял. Копию не делает, но и ориентацию потоку не задает никакую, видимо из-за использования низкоуровневых write() и друзей. В общем-то проще на всякий случай перед каждой инициализацией/деиниц вызывать (на винде работать не будет):

freopen(nullptr, "r", stdin); freopen(nullptr, "w", stdout); freopen(nullptr, "w", stderr); 

Стандарт же говорит о потоках, а не файлах, на которые они указывают.

И с файлами та же история, у них тоже ориентация, которая задётся при первой записи через высокоуровневый интерфейс, склонен думать, что дело именно в конверсии между широкими символами и локалью силами libc.

anonymous
( 02.06.21 01:01:41 MSK )

Мне тут ещё вот чего захотелось — сделать какой-то трейс для софтины, но не так, что после кор дампа или в отладчике, а программа чтобы отработала и в процессе скидывала в файл каждый вызов/выход и функции. Погуглил, несколько готовых вариантов не завелись, накостылил даже свой, работает на основе -finstrument-functions, получаю на выходе вроде такого:

begin initscr b newterm b new_prescr end new_prescr b newterm_sp b _nc_setupterm b _nc_setup_tinfo b _nc_read_entry b _nc_pathlast e _nc_pathlast b _nc_first_db . 

меня бы это даже устроил даже не смотря на то, что запускаю под отладчиком и задаю размер таблицы в .dynsym секции руками там же (так не въехал как его узнать иначе). Но есть большой косяк — поделка ище имена символ в таблице экспорта (компилю с -rdynamic), но static функции в данную таблицу не попадают. Может есть готовое решение моей хотелки без данного недостатка?

одновременная работа с std::wcout и std::cout

Когда wcout/cout вызывается впервые, устанавливается определенная ориентация stdout (стандартный поток вывода). В случае cout поток становится однобайтно-ориентированным, а в случае wcout поток становится ориентированным на широкоформатные символы. Согласно стандарту C++ [27.4.1] и стандарту С [7.19.2] (C11 [7.21.2]), однажды установив ориентацию stdout нельзя вызывать функции несовместимые с установленной ориентацией.

Отслеживать
ответ дан 16 авг 2018 в 5:36
1,746 1 1 золотой знак 6 6 серебряных знаков 10 10 бронзовых знаков

Как и было сказано одновременно печатать с разными форматами нельзя. Но. Можно закрыть поток и открыть. Этим редко кто занимается.

# include # include int main()

Отслеживать
ответ дан 16 авг 2018 в 6:13
17.1k 1 1 золотой знак 9 9 серебряных знаков 33 33 бронзовых знака

  • c++
  • utf-8
  • вывод
  • кириллица
    Важное на Мете
Похожие

Подписаться на ленту

Лента вопроса

Для подписки на ленту скопируйте и вставьте эту ссылку в вашу программу для чтения RSS.

Дизайн сайта / логотип © 2023 Stack Exchange Inc; пользовательские материалы лицензированы в соответствии с CC BY-SA . rev 2023.10.27.43697

Нажимая «Принять все файлы cookie» вы соглашаетесь, что Stack Exchange может хранить файлы cookie на вашем устройстве и раскрывать информацию в соответствии с нашей Политикой в отношении файлов cookie.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *