Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
 
Рейтинг 4.73/11: Рейтинг темы: голосов - 11, средняя оценка - 4.73
1402 / 644 / 135
Регистрация: 11.08.2011
Сообщений: 2,299
Записей в блоге: 2
1

Разница между fwrite, cout и cout.write

31.07.2018, 10:38. Показов 2013. Ответов 8
Метки нет (Все метки)

Привет.

Пытаюсь вывести букву 'ф' в консоль Windows 7, используя кодировку UTF-8. Для этого меняю кодовую страницу консоли на CP_UTF8, потом пытаюсь вывести UTF-8 строку при помощи 3х разных функций: fwrite, cout и cout.write. Из них букву ф выводит только fwrite, а cout и cout.write выводят мусор: обе они выводят по 2 символа прямоугольника. Похоже на то, что cout и cout.write заставляют консоль интерпретировать 2 байта одного символа за 2 разных символа, но вопрос почему так происходит?

Почему fwrite работает, а cout и cout.write не работают?

Вот мой код:

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#include <iostream>
#include <cstdio>
#include <cstddef>
#include <Windows.h>
 
int main() {
     using namespace std;
 
     UINT old_cp = GetConsoleOutputCP();
     bool is_code_page_changed = false;
     if(old_cp != CP_UTF8) {
       if(!SetConsoleOutputCP(CP_UTF8)) {
        cerr << "Error while changing code page" << endl;
        return 0;
       }
       is_code_page_changed = true;
     }
    constexpr char str[] = u8\n";
    constexpr size_t len = sizeof(str) / sizeof(str[0]) - 1; // == 3
    fwrite(str, sizeof(str[0]), len, stdout);
    cout << str;
    cout.write(str, len);
 
    if(is_code_page_changed) {
        SetConsoleOutputCP(old_cp);
    }
}
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
31.07.2018, 10:38
Ответы с готовыми решениями:

В чем разница std::cout и просто cout?
Ребят ,подскажите на простом языке для чайников . В чем разница std::cout и просто cout?

Разница между cout и _tprintf
Господа, когда я вывожу на экран значение ф-ции GetComputerNameEx с помощью cout, получаются...

Cout <<endl; Что это значит? Если ничего нету в cout?
Здравствуйте ! Обьясните пожалуйста что значит cout &lt;&lt;endl; если он используется после цикла...

Подскажите почему после первого cout программа не останавливается для ввода строки, а выводит второй cout
Подскажите почему после первого cout программа не останавливается для ввода строки, а выводит...

8
918 / 635 / 198
Регистрация: 08.09.2013
Сообщений: 1,690
31.07.2018, 12:30 2
Включить буферизацию потока не пробовали?
C++
1
setvbuf(stdout, nullptr, _IOFBF, 1000);
Этот костыль, конечно, лучше не использовать, но похоже, вендовые текстовые потоки до сих пор не умеют utf-8.
1
1402 / 644 / 135
Регистрация: 11.08.2011
Сообщений: 2,299
Записей в блоге: 2
31.07.2018, 12:49  [ТС] 3
gng, да, пробовал. После этого все 3 функции выводят одинаковые мусорные символы.
0
1402 / 644 / 135
Регистрация: 11.08.2011
Сообщений: 2,299
Записей в блоге: 2
01.08.2018, 11:31  [ТС] 4
Актуально.
0
1306 / 911 / 421
Регистрация: 30.10.2017
Сообщений: 2,559
01.08.2018, 11:48 5
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <iostream>
#include <Windows.h>
#include <io.h>
#include <fcntl.h>
 
using namespace std;
 
int main()
{
    _setmode(_fileno(stdout), _O_U16TEXT); // или _O_U8TEXT для UTF-8
    _setmode(_fileno(stdin), _O_U16TEXT);
    _setmode(_fileno(stderr), _O_U16TEXT);
 
    constexpr wchar_t str[] = L\n";
    wcout << str;
 
    system("pause");
    return 0;
}
0
Модератор
Эксперт С++
11071 / 9128 / 5485
Регистрация: 18.12.2011
Сообщений: 24,399
01.08.2018, 11:49 6
А у меня получилось, если написать так:
C++
1
2
3
4
    setvbuf(stdout, nullptr, _IOFBF, 1000);
    fwrite(str, sizeof(str[0]), len, stdout);
    cout << str;
    cout.write(str, len);
0
1402 / 644 / 135
Регистрация: 11.08.2011
Сообщений: 2,299
Записей в блоге: 2
01.08.2018, 13:41  [ТС] 7
zss, все 3 функции выводят верный результат?

QuakerRUS, спасибо, но меня интересует не вывод юникодовых символов, а то, почему получилась разница между результатом работы fwrite и cout.write.
0
Модератор
Эксперт С++
11071 / 9128 / 5485
Регистрация: 18.12.2011
Сообщений: 24,399
01.08.2018, 14:46 8
Цитата Сообщение от Dani Посмотреть сообщение
все 3 функции выводят верный результат
Да(среда VS 2017), только еще пришлось сбросить буфер:
C++
1
2
3
4
5
setvbuf(stdout, nullptr, _IOFBF, 1000);
fwrite(str, sizeof(str[0]), len, stdout);
cout << str;
cout.write(str, len);
cout.flush();
0
1306 / 911 / 421
Регистрация: 30.10.2017
Сообщений: 2,559
01.08.2018, 14:51 9
\n уберите из значения и endl добавьте в конце cout, тогда сбрасывать буфер не придется.
0
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
01.08.2018, 14:51

Cout like: перегрузить оператор<< по примеру объекта cout для extern объекта пользовательского типа
Мне нужен extern объект по примеру cout с перегруженным оператором. Я нечто подобное сделал, только...

cout.setf и cout.precision
Здравствуйте. В одной книге увидел строчку кода: cout.precision(2); cout.setf(ios::fixed,...

Cout - пробел между символами
cout &lt;&lt; &quot;Точка с координатами (&quot; &lt;&lt; x &lt;&lt; y &lt;&lt; &quot;)&quot; &lt;&lt; endl; Нужно, что бы выводило: Точка...

cout vs. std::cout
всем доброго времени суток. начал самостоятельно изучать c++. скачал в сети много разныx умныx...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
9
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2021, vBulletin Solutions, Inc.