Форум программистов, компьютерный форум, киберфорум
Наши страницы

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
 
Рейтинг: Рейтинг темы: голосов - 322, средняя оценка - 4.78
M128K145
Эксперт JavaЭксперт С++
8316 / 3536 / 143
Регистрация: 03.07.2009
Сообщений: 10,708
#1

Флаги форматирования и манипуляторы - C++

08.09.2009, 21:36. Просмотров 42646. Ответов 45

У многих новичков возникают вопросы, как вывести число в таком-то формате, а можно вывести так или так. Чтоб стало более ясно, вот небольшая
программка с комментариями.
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
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
#include <iostream>
#include <iomanip>
int main()
{
    setlocale(LC_ALL, "Russian");
    char _char[] = "char\n"; 
    int _int = 20;
    int negative_int = -10;
    double _double = 123.5467;
    float zero_float = 10;
 
//======== работаем с выравниванием ========\\
    
    std::cout<<"Работаем с выравниванием\n";
    //устанавливаем ширину поля вывода
    std::cout.width (20);
    //устанавливаем символ заполнитель(по умолчанию - пробел)
    std::cout.fill ('_');
    //флаг форматирования при котором знак числа выводится по левому краю, 
    //число — по правому. Промежуток заполняется символами заполнителя
    std::cout.setf(std::ios::internal);
    std::cout<<negative_int<<std::endl;
 
    //устанавливаем ширину поля вывода
    std::cout.width(50);
    //устанавливаем символ заполнитель(по умолчанию - пробел)
    std::cout.fill ('/');
    //выравниваем по правому краю поля
    std::cout.setf(std::ios::right);
    std::cout<<_char<<std::endl;
 
    //P.S. флаги  left, right и internal не могут быть установлены одновременно.
 
//======== выводим в разных системах исчисления ========\\
 
    std::cout<<"Выводим в разных системах исчисления\n";
    //восьмеричная система счисления
    std::cout.flags(std::ios::oct);
    std::cout<<_int<<std::endl;
 
    //десятичная система счисления
    std::cout.flags(std::ios::dec);
    std::cout<<_int<<std::endl;
 
    //шестнадцатеричная система счисления
    std::cout.flags(std::ios::hex);
    std::cout<<_int<<std::endl;
 
    //задаем основание системы счисления (8, 16, 10 или 0)
    //по умолчанию 0 - это десятичное, кроме случаев, когда вводятся 8- или
    //16-ричные числа. Здесь к примеру основание 8
    std::cout<<std::setbase(8)<<_int<<std::endl;
 
    //P.S. флаги dec, oct и hex не могут быть установлены одновременно.
 
//======== выводим вещественные чисел ========\\
 
    std::cout<<"\nВыводим вещественные числа\n";
    //при выводе вещественных чисел печатаем десятичную точку и дробную часть
    std::cout.flags(std::ios::showpoint);
    std::cout<<zero_float<<std::endl;
 
    //печатаем вещественные числа в форме мантиссы с порядком
    std::cout.flags(std::ios::scientific);
    std::cout<<_double<<std::endl;
    
    //Печатаем вещественные числа в форме с фиксированной точкой, 
    //точность определяем строкой ниже в setprecision
    std::cout.flags(std::ios::fixed);
    std::cout<<std::setprecision(2)<<_double<<std::endl;
 
    //P.S. флаги scientific и fixed не могут быть установлены одновременно
 
//======== печатаем знаки ========\\
 
    std::cout<<"\nПечатаем знаки\n";
    //печатаем знак при выводе положительных чисел
    std::cout.flags(std::ios::showpos);
    std::cout<<_int<<std::endl;
 
    system("pause");
    return 0;
}
Я выбирал самые основные. Кто может добавить, если я что-то пропустил - добавляйте. Буду только благодарен
19
Лучшие ответы (1)
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
08.09.2009, 21:36
Я подобрал для вас темы с готовыми решениями и ответами на вопрос Флаги форматирования и манипуляторы (C++):

Манипуляторы и флаги формата - C++
1.Манипулятор right почемуто не производит вывод по правой стороне. В чем проблема? рис. 1 2.Манипулятор skipws должен отбрасывать...

Манипуляторы ввода-вывода. Флаги - C++
Здравствуйте. Моя задача такова: нужно сделать программу, которая будет ждать ввода числа в 16-ричной, 8-ричной или 10-тичной системе...

Пользовательские флаги формата потока и манипуляторы - C++
Всем здравствуйте, возникла такая вот проблема: не понимаю как правильно создать свой флаг формата и правильно указать его для потока...

Флаги форматирования cout - C++
В чем разница, кроме того, что первые два флага форматирования задаются в качестве манипуляторов? cout &lt;&lt; setiosflags(ios::fixed); ...

Флаги форматирования в cout, выравнивание справа - C++
Вот код. Я установил флаг форматирования райт. Поток перегружен и на консоль выводится площадь и периметр, вот только они нисколько не...

Манипуляторы - C++
Ребята, проблема с манипуляторами.. Вместо того чтобы были пустые места, программа выдает нули(( void view(HANDLE hrFile) { ...

45
taras atavin
3888 / 1762 / 92
Регистрация: 24.11.2009
Сообщений: 27,565
24.06.2012, 15:20 #31
Чего с чаром возиться? Табличное преобразование и ни каких гвоздёв.

Добавлено через 1 минуту
Да и можно же так:
C++
1
2
3
char c;
c=-1;
cout<<(int)(unsigned char)c;
Старшие биты заполнятся нолями и ни каких гвоздёв.

Добавлено через 2 минуты
Цитата Сообщение от Петррр Посмотреть сообщение
http://www.cplusplus.com/reference/c.../cstdlib/itoa/
А без принтфа? А то он для меня до сих пор сложнее иероглифов.
0
kazak
3057 / 2378 / 160
Регистрация: 11.03.2009
Сообщений: 5,438
Завершенные тесты: 1
24.06.2012, 15:27 #32
Цитата Сообщение от taras atavin Посмотреть сообщение
А без принтфа? А то он для меня до сих пор сложнее иероглифов.
Для потоков можно писать свои собственные манипуляторы.

Добавлено через 4 минуты
Цитата Сообщение от Evg Посмотреть сообщение
В первом случае напечатается "ff", что логично, во втором - "ffffffff", что не логично (с точки зрения постановки задачи)
C++
1
cout << (c&0xff)
можно так попробовать.
2
Evg
Эксперт CАвтор FAQ
18884 / 6840 / 498
Регистрация: 30.03.2009
Сообщений: 19,260
Записей в блоге: 30
24.06.2012, 15:35 #33
Цитата Сообщение от grizlik78 Посмотреть сообщение
Над хорошим способом надо подумать, а если надо по-быстрому вывести именно байты, то можно так
Да я знаю, как это сделать через онанизм. У меня вопрос: можно ли сделать без онанизма? Ответ уже вроде бы как получен, что нет. Это 100%?
0
grizlik78
Эксперт С++
1981 / 1474 / 127
Регистрация: 29.05.2011
Сообщений: 3,047
24.06.2012, 15:37 #34
Цитата Сообщение от Evg Посмотреть сообщение
Ответ уже вроде бы как получен, что нет. Это 100%?
По-крайней мере манипуляторов таких нет. А способ с маской мне понравился.
0
taras atavin
3888 / 1762 / 92
Регистрация: 24.11.2009
Сообщений: 27,565
24.06.2012, 15:46 #35
Цитата Сообщение от kazak Посмотреть сообщение
Для потоков можно писать свои собственные манипуляторы.
Как? Дай, пожалуйста ссылку на туториал.

Добавлено через 1 минуту
Цитата Сообщение от Evg Посмотреть сообщение
Да я знаю, как это сделать через онанизм. У меня вопрос: можно ли сделать без онанизма?
Именно через него ты и просишь.
0
Evg
Эксперт CАвтор FAQ
18884 / 6840 / 498
Регистрация: 30.03.2009
Сообщений: 19,260
Записей в блоге: 30
24.06.2012, 15:56 #36
Цитата Сообщение от grizlik78 Посмотреть сообщение
А способ с маской мне понравился.
С маской или с преобразованием типа - оно годится лишь само по себе. А ведь в Си++ есть такое мощное средство как шаблон, в котором такие способы превращают код в бардак (со специализациями) на ровном месте
0
kazak
3057 / 2378 / 160
Регистрация: 11.03.2009
Сообщений: 5,438
Завершенные тесты: 1
24.06.2012, 16:08 #37
Цитата Сообщение от taras atavin Посмотреть сообщение
Как? Дай, пожалуйста ссылку на туториал.
http://xprogramming.narod.ru/Trash/Chapter9.htm#8
http://www.firststeps.ru/mfc/msdn/r.php?173
0
taras atavin
3888 / 1762 / 92
Регистрация: 24.11.2009
Сообщений: 27,565
24.06.2012, 16:16 #38
Цитата Сообщение от Evg Посмотреть сообщение
превращают код в бардак (со специализациями) на ровном месте
Каким образом шаблон, навёрнутый на сериализацию всегда в байты может добавить бардака?

Добавлено через 2 минуты
Цитата Сообщение от kazak Посмотреть сообщение
http://xprogramming.narod.ru/Trash/Chapter9.htm#8
http://www.firststeps.ru/mfc/msdn/r.php?173
Вижу использование готовых манипуляторов. А где создание?
0
grizlik78
Эксперт С++
1981 / 1474 / 127
Регистрация: 29.05.2011
Сообщений: 3,047
24.06.2012, 16:18 #39
Evg, да, к сожалению C++ неидеален, как и мир. Но это ты и сам знаешь
Придётся или специализации писать, или свой потоковый класс, на использование которого, кстати, можно переключать с использованием своего манипулятора. Кажется
Только в классе том вряд ли без специализаций обойтись. нет в жизни счастья.

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

Добавлено через 1 минуту
taras atavin, манипулятор — обычная функция, принимающая ссылку на поток и возвращающая ссылку на поток.
0
taras atavin
3888 / 1762 / 92
Регистрация: 24.11.2009
Сообщений: 27,565
24.06.2012, 16:26 #40
Эйси. А как её писать? Ведь мне же не в манипулятор потом выводить оператором <<, а в сам поток. Как управление передаётся? Или что он делает?
0
Evg
Эксперт CАвтор FAQ
18884 / 6840 / 498
Регистрация: 30.03.2009
Сообщений: 19,260
Записей в блоге: 30
24.06.2012, 16:31 #41
Цитата Сообщение от grizlik78 Посмотреть сообщение
Evg, да
Пичалька...
0
ForEveR
В астрале
Эксперт С++
7992 / 4751 / 321
Регистрация: 24.06.2010
Сообщений: 10,547
Завершенные тесты: 3
24.06.2012, 16:33 #42
Создание (вернее, внедрение) манипулятора сообщение №2
0
grizlik78
Эксперт С++
1981 / 1474 / 127
Регистрация: 29.05.2011
Сообщений: 3,047
24.06.2012, 16:44 #43
Цитата Сообщение от grizlik78 Посмотреть сообщение
свой потоковый класс, на использование которого, кстати, можно переключать с использованием своего манипулятора. Кажется
Эх, размечтался я... Фиг чего сделаешь полезного пользовательскими манипуляторами стандартным путём.
0
Evg
Эксперт CАвтор FAQ
18884 / 6840 / 498
Регистрация: 30.03.2009
Сообщений: 19,260
Записей в блоге: 30
24.06.2012, 17:49 #44
Цитата Сообщение от grizlik78 Посмотреть сообщение
А способ с маской мне понравился.
Кстати, этот способ неправильно отработает для отрицательных величин

C
#include <stdio.h>
 
int main (void)
{
  char c = -1;
  printf ("%hhd\n", c);
  return 0;
}
C++
#include <iostream>
 
int main (void)
{
  char c = -1;
  std::cout << (c & 0xff) << std::endl;
  return 0;
}
Первый код выдаст "-1", второй - "255". Второй результат неверен, т.к. знаковый char не может иметь значение 255 (ибо диапазон от -128 до +127). Получается, что при печати char'а надо заниматься онанизмом, который дополнительно классифицируется на знаковые и беззнаковые случаи (а печать 16-ричного представления всегда относится к беззнаковому)
0
grizlik78
Эксперт С++
1981 / 1474 / 127
Регистрация: 29.05.2011
Сообщений: 3,047
24.06.2012, 18:43 #45
То, что простые методы не универсальны — это очевидно. Мне и самому не нравятся многие ограничения, присущие потоковому выводу. Делать простые вещи иногда приходится сложным образом.
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
28
29
30
#include <iostream>
 
class char_to_out
{
    char c;
public:
    explicit char_to_out(char c) : c(c)
    {}
    std::ostream& out(std::ostream& os) const
    {
        if (os.flags() & (std::ios::hex | std::ios::oct))
            os << (c & 0xff);
        else
            os << (int)c;
        return os;
    }
};
 
inline
std::ostream& operator<<(std::ostream& os, char_to_out const & c)
{
    return c.out(os);
}
 
int main()
{
    char c = -1;
    std::cout << char_to_out(c) << std::endl;
    std::cout << std::hex << char_to_out(c) << std::endl;
}
В принципе, при выводе вместо char_to_out можно подставить шаблонную функцию для универсальности (или класс параметризовать), но без специализаций здесь не обойтись, похоже. Потоки, похоже, изначально не слишком хорошо продуманы, хотя идея красивой была.

Добавлено через 22 минуты
Более полная версия, которая годится (улучшать можно и дальше) для использования в шаблонах:
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
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
#include <iostream>
 
template <typename TYPE>
class some_to_out_class
{
    TYPE const& v;
public:
    explicit some_to_out_class(TYPE const& v) : v(v)
    {}
    std::ostream& out(std::ostream& os) const
    {
        return (os << v);
    }
};
 
template <>
inline
std::ostream& some_to_out_class<char>::out(std::ostream& os) const
{
    if (os.flags() & (std::ios::hex | std::ios::oct))
        os << (v & 0xff);
    else
        os << (int)v;
    return os;
}
 
template <>
inline
std::ostream& some_to_out_class<signed char>::out(std::ostream& os) const
{
    if (os.flags() & (std::ios::hex | std::ios::oct))
        os << (v & 0xff);
    else
        os << (int)v;
    return os;
}
 
template <>
inline
std::ostream& some_to_out_class<unsigned char>::out(std::ostream& os) const
{
    return os << (v & 0xff);
}
 
template <typename TYPE>
inline
std::ostream& operator<<(std::ostream& os, some_to_out_class<TYPE> const & v)
{
    return v.out(os);
}
 
template <typename TYPE>
inline
some_to_out_class<TYPE> some_to_out(TYPE const& v)
{
    return some_to_out_class<TYPE>(v);
}
 
int main()
{
    char c = -1;
    std::cout << some_to_out(c) << std::endl;
    std::cout << std::hex << some_to_out(c) << std::endl;
}
Если кто знает методы проще — предлагайте.
0
24.06.2012, 18:43
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
24.06.2012, 18:43
Привет! Вот еще темы с ответами:

манипуляторы - C++
Создайте свои манипуляторы которые будут выполнять 1)вывод всех символов равных заданному заменить пробелом 2)вывод всех символов...

Манипуляторы. От С к С++ - C++
fprintf(f1, “%-7.3е”, x) Какая эквивалентная запись этой на С++?

манипуляторы - C++
Создайте манипулятор ввода skipcbar(), который, поочередно, то считывает, то пропускает каждые десять символов потока ввода.

Манипуляторы в С++ - C++
___________________Манипуляторы______________________ - endl_________________перевод строки - flush________________выгружает содержимое...


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

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

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