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 т.е. Русские буквы не вводятся и не выводятся. Где я не прав? Подскажите, пожалуйста.

Оглавление

  • Ввод и вывод wcin & wcout, Fuzzy, 11:35 , 10-Дек-08, ( 1 )
    • Ввод и вывод wcin & wcout, sy, 12:55 , 10-Дек-08, ( 2 )
    • Ввод и вывод wcin & wcout, sy, 14:56 , 10-Дек-08, ( 5 )
      • Ввод и вывод wcin & wcout, vic, 15:07 , 10-Дек-08, ( 6 )
        • Ввод и вывод wcin & wcout, Аноним, 14:04 , 11-Дек-08, ( 7 )
          • Ввод и вывод wcin & wcout, vic, 15:31 , 11-Дек-08, ( 8 )

          Сообщения по теме [Сортировка по времени | 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);

          .
          }


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

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

          Форум русскоязычного сообщества Ubuntu

          Страница сгенерирована за 0.074 секунд. Запросов: 25.

          • Сайт
          • Об Ubuntu
          • Скачать Ubuntu
          • Семейство Ubuntu
          • Новости
          • Форум
          • Помощь
          • Правила
          • Документация
          • Пользовательская документация
          • Официальная документация
          • Семейство Ubuntu
          • Материалы для загрузки
          • Совместимость с оборудованием
          • RSS лента
          • Сообщество
          • Наши проекты
          • Местные сообщества
          • Перевод Ubuntu
          • Тестирование
          • RSS лента

          © 2012 Ubuntu-ru — Русскоязычное сообщество Ubuntu Linux.
          © 2012 Canonical Ltd. Ubuntu и Canonical являются зарегистрированными торговыми знаками Canonical Ltd.

          Обработка строк в C++/WinRT

          С помощью C++/WinRT можно вызывать интерфейсы API среды выполнения Windows, используя типы широких строк стандартной библиотеки C++, такие как std::wstring (но не типы узких строк, такие как std::string). В C++/WinRT имеется настраиваемый строковый тип winrt::hstring (определенный в базовой библиотеке C++/WinRT — %WindowsSdkDir%Include\\cppwinrt\winrt\base.h ). Этот строковый тип фактически принимают и возвращают конструкторы, функции и свойства среды выполнения Windows. Но, во многих случаях благодаря конструкторам преобразования hstring и операторам преобразования можно выбирать, следует ли учитывать hstring в коде клиента. Если вы разрабатываете интерфейсы API, вероятность того, что вам нужно знать о hstring, возрастает.

          В C++ существует множество строковых типов. Различные варианты существуют во множестве библиотек в дополнение к std::basic_string из стандартной библиотеки C++. В С++17 имеются служебные программы для преобразования строк и std::basic_string_view, чтобы заполнить пробелы между всеми строковыми типами. Тип winrt::hstring дает возможность преобразования с помощью std::wstring_view для обеспечения взаимодействия, для которого был создан std::basic_string_view.

          Использование std::wstring (и, при необходимости, winrt::hstring) с Uri

          public: Uri(winrt::hstring uri) const; 

          Но hstring имеет конструкторы преобразования, позволяющие работать с ним, не учитывая этот факт. Ниже приведен пример кода, показывающий, как создать Uri из литерала широкой строки, представления широкой строки и std::wstring.

          #include #include using namespace winrt; using namespace Windows::Foundation; int main() < using namespace std::literals; winrt::init_apartment(); // You can make a Uri from a wide string literal. Uri contosoUri< L"http://www.contoso.com" >; // Or from a wide string view. Uri contosoSVUri< L"http://www.contoso.com"sv >; // Or from a std::wstring. std::wstring wideString< L"http://www.adventure-works.com" >; Uri awUri< wideString >; > 

          Метод доступа к свойству Uri::Domain имеет тип hstring.

          public: winrt::hstring Domain(); 
          // Access a property of type hstring, via a conversion operator to a standard type. std::wstring domainWstring< contosoUri.Domain() >; // L"contoso.com" domainWstring = awUri.Domain(); // L"adventure-works.com" // Or, you can choose to keep the hstring unconverted. hstring domainHstring< contosoUri.Domain() >; // L"contoso.com" domainHstring = awUri.Domain(); // L"adventure-works.com" 
          public: hstring ToString() const; 

          Uri реализует интерфейс IStringable.

          // Access hstring's IStringable::ToString, via a conversion operator to a standard type. std::wstring tostringWstring< contosoUri.ToString() >; // L"http://www.contoso.com/" tostringWstring = awUri.ToString(); // L"http://www.adventure-works.com/" // Or you can choose to keep the hstring unconverted. hstring tostringHstring< contosoUri.ToString() >; // L"http://www.contoso.com/" tostringHstring = awUri.ToString(); // L"http://www.adventure-works.com/" 

          Можно использовать функцию hstring::c_str для получения стандартной широкой строки из hstring (так же, как и из std::wstring).

          #include std::wcout  

          Если у вас есть hstring, значит, вы можете получить Uri.

          Uri awUriFromHstring< tostringHstring >; 

          Рассмотрим метод, который принимает hstring.

          public: Uri CombineUri(winrt::hstring relativeUri) const; 

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

          std::wstring contact< L"contact" >; contosoUri = contosoUri.CombineUri(contact); std::wcout  

          Для hstring имеется член-оператор преобразования std::wstring_view, и преобразование осуществляется без дополнительных затрат.

          void legacy_print(std::wstring_view view); void Print(winrt::hstring const& hstring)

          Функции и операторы winrt::hstring

          Для winrt::hstring реализован ряд конструкторов, операторов, функций и итераторов.

          Тип hstring является диапазоном, поэтому вы можете использовать его с основанным на диапазоне for или с std::for_each . Он также предоставляет операторы сравнения для естественного и эффективного сравнения с его аналогами в стандартной библиотеке C++. Кроме того, он включает в себя все, что необходимо для использования hstring в качестве основы для ассоциативных контейнеров.

          Мы понимаем, что многие библиотеки C++ используют std::string и работают только с текстом UTF-8. Для удобства мы предоставляем вспомогательные методы, такие как winrt::to_string и winrt::to_hstring, для двустороннего преобразования.

          WINRT_ASSERT — это макроопределение, которое передается в _ASSERTE.

          winrt::hstring w< L"Hello, World!" >; std::string c = winrt::to_string(w); WINRT_ASSERT(c == "Hello, World!"); w = winrt::to_hstring(c); WINRT_ASSERT(w == L"Hello, World!"); 

          Дополнительные примеры и сведения о функциях и операторах hstring приведены в справочных материалах по API winrt::hstring.

          Обоснование для winrt::hstring и winrt::param::hstring

          Среда выполнения Windows реализуется в знаках wchar_t, но двоичный интерфейс приложения (ABI) среды выполнения Windows не является подмножеством того, что предоставляют std::wstring или std::wstring_view. Их использование приведет к значительной неэффективности. Вместо этого C++/WinRT предоставляет winrt::hstring, представляющий собой неизменяемую строку, согласованную с базовым HSTRING и реализованную за интерфейсом, аналогичным std::wstring.

          Можно заметить, что входные параметры C++/ WinRT, которые логически должны принимать winrt::hstring, фактически ожидают winrt::param::hstring. Пространство имен param содержит набор типов, используемых исключительно для оптимизации входных параметров для естественной привязки к типам стандартной библиотеки C++, а также позволяющих избежать копий и других аспектов, снижающих эффективность. Эти типы не следует использовать напрямую. Если вы хотите использовать оптимизацию для собственных функций, применяйте std::wstring_view. Также см. статью о передаче параметров в интерфейс ABI.

          Идея состоит в том, что вы можете по большей части игнорировать особенности управления строками среды выполнения Windows и просто эффективно работать с тем, что вам известно. Это важно, учитывая, насколько активно строки используются в среде выполнения Windows.

          Форматирование строк

          Одно из средств форматирования строк — std::wstringstream. Вот пример, который форматирует и отображает простое сообщение отладочной трассировки.

          #include #include #include . void MainPage::OnPointerPressed(winrt::Windows::UI::Xaml::Input::PointerRoutedEventArgs const& e) < winrt::Windows::Foundation::Point const point< e.GetCurrentPoint(nullptr).Position() >; std::wostringstream wostringstream; wostringstream

          Правильный способ задать свойство

          Для установки свойств значение передается в функцию задания. Приведем пример.

          // The right way to set the Text property. myTextBlock.Text(L"Hello!"); 

          Ниже приведен неправильный код. Компиляция происходит, но все, что выполняется — это изменение значения winrt::hstring, возвращаемое функцией получения доступаText(), а затем результаты отклоняются.

          // *Not* the right way to set the Text property. myTextBlock.Text() = L"Hello!"; 

          Важные API

          • Структура winrt::hstring
          • Функция winrt::to_hstring
          • Функция winrt::to_string

          Что лучше использовать: cout / wcout или printf? [закрыт]

          Хотите улучшить этот вопрос? Переформулируйте вопрос так, чтобы он был сосредоточен только на одной проблеме.

          Закрыт 5 лет назад .
          Собственно, вопрос в заголовке. Пожалуйста, дайте подробный ответ.
          Отслеживать
          20.2k 6 6 золотых знаков 38 38 серебряных знаков 81 81 бронзовый знак
          задан 13 июл 2018 в 16:02
          Mournehowl Mournehowl
          153 15 15 бронзовых знаков

          Вопрос вполне идентичен вопросу: " Что лучше использовать: шуруповерт , дрель или перфоратор? .." Каждый инструмент хорош при разных задачах и ситуаций.

          13 июл 2018 в 16:21

          Что удобнее, то и используйте. Как уже ответили cout безопаснее, нет необходимости указывать тип, который выводишь. С другой стороны можно быстро написать printf("count %i with %s, or %s", i, data, foo); С cout это выглядело бы cout
          13 июл 2018 в 16:24

          Хотите удобно и безопасно - используйте boost::format Предыдущий пример запишется так: cout
          13 июл 2018 в 19:10

          На моей практике, добиться красиво отформатированного вывода (особенно при модификации программ) с printf -ом получается быстрее

          13 июл 2018 в 20:31

          1 ответ 1

          Сортировка: Сброс на вариант по умолчанию

          Как завещал нам Страуструп, лучше потоки чем printf. Ибо потоки, как минимум, типобезопасны.

          Например есть код:

          int i; cout 

          Представим, что в процессе работы пришлось сменить тип переменной (это встречается сплошь и рядом):

          float i; cout 

          Как видно, при использовании потока ничего не поменялось. А при использовании printf пришлось править форматную строку. Если printf много в коде, то везде править форматную строку во всех printf очень утомительно и черевато ошибками.

          Предположить легко. Однако, на самом деле это последствие идеи предоставления пользователям языка средств для его расширения -- т.е. конструирования собственных типов данных и операций над ними, что влечет перегрузку операций (т.е. одно и то же обозначение операций в зависимости от типов операндов дает разный результат). Хорошо это или плохо для реальной практики программирования, учитывающей качество персонала, вопрос дискуссионный

          Уж не знаю насколько потоки следствие идеи перегрузки операций. Может быть это и так. В любом случае, в варианте с printf тип операнда указывается два раза. Один раз в форматной строке, а второй раз собственно имя переменной говорит компилятору какой это тип. А два раза повторять одну и ту же информацию не есть хорошо. Потому что править приходится в двух местах, а не в одном месте. Так что идея с потоками (независимо от источника ее появления, будь то перегрузка операций или просто желание избавится от форматной строки) еще позволила избавится от ненужного дублирования информации.

          Кстати, перегрузить операции можно было бы и с printf. Или в потоках оставить форматную строку. Ну если все делать через одно место конечно.

          Что касается квалификации персонала, то квалификация постоянно растет. Старая школа может долбать любимый printf до посинения, пока самим не надоест вылавливать ошибки форматов. Новое поколение не знает таких ужасов и весело применяет потоки.

          Кстати, вывод через потоки в общем случае быстрее, чем вывод через printf. Объясняется это тем, что при выводе через потоки разбор типов происходит на этапе компиляции и в рантайме разбора типов нет, а там есть только вывод значения. В случае же с printf происходит разбор форматной строки в рантайме, то есть компилированный код передает управление интерпретатору форматной строки. А, как известно, интерпретатор работает в 100-1000 раз медленнее, чем компилированный код.

          Ранние трансляторы С++ создавали потоковый вывод как надстройку над выводом printf и разницы в скорости не было (но все равно была разница в типобезопасности, так как форматные строки формировались автоматически). Современные трансляторы С++ делают потоковый вывод как надо, без использования printf. И это (теоретически) повышает быстродействие вывода.

          Так что скорость вывода это еще один аргумент, который заставляет программистов выбирать потоки вместо старого подхода с printf.

          Но и объем скомпилированного кода больше.

          Объем скомпилированного кода при выводе в поток не больше, чем при использовании printf.

          int var1=1; int var2=2; cout 

          В этом примере строки вывода

          cout 

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

          скорость встроенных при компиляции (как следствие реализации templates) преобразований выше.

          Скорость вывода при использовании printf меньше именно из-за того, что разбор форматной строки происходит в рантайме. В случае использования потоков нет разбора форматной строки в рантайме и также нет оверхеда из-за шаблонов потому что там вставляется не шаблон, а обычный вызов подпрограммы вывода для соответствующего типа. Это легко проверить, если посмотреть ассемблерный код простого примера, приведенного выше. Транслятор Visual Studio 2017.

          ; Listing generated by Microsoft (R) Optimizing Compiler Version 19.14.26433.0 TITLE C:\user\basil\rttsched\etudes\etude2\etude2\etude2\etude2.cpp .686P .XMM include listing.inc .model flat INCLUDELIB MSVCRTD PUBLIC ?__empty_global_delete@@YAXPAX@Z ; __empty_global_delete PUBLIC ?__empty_global_delete@@YAXPAXI@Z ; __empty_global_delete PUBLIC _main EXTRN __imp_??6?$basic_ostream@DU?$char_traits@D@std@@@std@@QAEAAV01@H@Z:PROC EXTRN __RTC_CheckEsp:PROC EXTRN __RTC_InitBase:PROC EXTRN __RTC_Shutdown:PROC EXTRN __imp_?cout@std@@3V?$basic_ostream@DU?$char_traits@D@std@@@1@A:BYTE ; COMDAT rtc$TMZ rtc$TMZ SEGMENT __RTC_Shutdown.rtc$TMZ DD FLAT:__RTC_Shutdown rtc$TMZ ENDS ; COMDAT rtc$IMZ rtc$IMZ SEGMENT __RTC_InitBase.rtc$IMZ DD FLAT:__RTC_InitBase rtc$IMZ ENDS ; Function compile flags: /Odtp /RTCsu /ZI ; File c:\user\basil\rttsched\etudes\etude2\etude2\etude2\etude2.cpp ; COMDAT _main _TEXT SEGMENT _var2$ = -20 ; size = 4 _var1$ = -8 ; size = 4 _main PROC ; COMDAT push ebp mov ebp, esp sub esp, 216 ; 000000d8H push ebx push esi push edi lea edi, DWORD PTR [ebp-216] mov ecx, 54 ; 00000036H mov eax, -858993460 ; ccccccccH rep stosd mov DWORD PTR _var1$[ebp], 1 mov DWORD PTR _var2$[ebp], 2 mov esi, esp mov eax, DWORD PTR _var1$[ebp] push eax mov ecx, DWORD PTR __imp_?cout@std@@3V?$basic_ostream@DU?$char_traits@D@std@@@1@A call DWORD PTR __imp_??6?$basic_ostream@DU?$char_traits@D@std@@@std@@QAEAAV01@H@Z cmp esi, esp call __RTC_CheckEsp mov esi, esp mov eax, DWORD PTR _var2$[ebp] push eax mov ecx, DWORD PTR __imp_?cout@std@@3V?$basic_ostream@DU?$char_traits@D@std@@@1@A call DWORD PTR __imp_??6?$basic_ostream@DU?$char_traits@D@std@@@std@@QAEAAV01@H@Z cmp esi, esp call __RTC_CheckEsp xor eax, eax pop edi pop esi pop ebx add esp, 216 ; 000000d8H cmp ebp, esp call __RTC_CheckEsp mov esp, ebp pop ebp ret 0 _main ENDP _TEXT ENDS ; Function compile flags: /Odtp /RTCsu /ZI ; File c:\user\basil\rttsched\etudes\etude2\etude2\etude2\etude2.cpp ; COMDAT ?__empty_global_delete@@YAXPAXI@Z _TEXT SEGMENT ___formal$ = 8 ; size = 4 ___formal$ = 12 ; size = 4 ?__empty_global_delete@@YAXPAXI@Z PROC ; __empty_global_delete, COMDAT push ebp mov ebp, esp sub esp, 192 ; 000000c0H push ebx push esi push edi lea edi, DWORD PTR [ebp-192] mov ecx, 48 ; 00000030H mov eax, -858993460 ; ccccccccH rep stosd pop edi pop esi pop ebx mov esp, ebp pop ebp ret 0 ?__empty_global_delete@@YAXPAXI@Z ENDP ; __empty_global_delete _TEXT ENDS ; Function compile flags: /Odtp /RTCsu /ZI ; File c:\user\basil\rttsched\etudes\etude2\etude2\etude2\etude2.cpp ; COMDAT ?__empty_global_delete@@YAXPAX@Z _TEXT SEGMENT ___formal$ = 8 ; size = 4 ?__empty_global_delete@@YAXPAX@Z PROC ; __empty_global_delete, COMDAT push ebp mov ebp, esp sub esp, 192 ; 000000c0H push ebx push esi push edi lea edi, DWORD PTR [ebp-192] mov ecx, 48 ; 00000030H mov eax, -858993460 ; ccccccccH rep stosd pop edi pop esi pop ebx mov esp, ebp pop ebp ret 0 ?__empty_global_delete@@YAXPAX@Z ENDP ; __empty_global_delete _TEXT ENDS END 

          Видно, что вызов

          cout 

          разворачивается в обычный вызов подпрограммы

          call DWORD PTR __imp_??6?$basic_ostream@DU$char_traits@D@std@@@std@@QAEAAV01@H@Z 

          и никаких шаблонов тут нет.

          мы пишем программы не для компьютера, а для других программистов

          Довольно спорное утверждение. Проще переписать весь код, чем править чужое. Ибо невозможно до конца понять, какие мысли (часто неверные) были у человека, когда он писал код.

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

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

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

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