Форум программистов, компьютерный форум CyberForum.ru

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

Восстановить пароль Регистрация
 
 
Рейтинг: Рейтинг темы: голосов - 322, средняя оценка - 4.78
M128K145
Эксперт C++
 Аватар для M128K145
8272 / 3491 / 142
Регистрация: 03.07.2009
Сообщений: 10,707
08.09.2009, 21:36     Флаги форматирования и манипуляторы #1
У многих новичков возникают вопросы, как вывести число в таком-то формате, а можно вывести так или так. Чтоб стало более ясно, вот небольшая
программка с комментариями.
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;
}
Я выбирал самые основные. Кто может добавить, если я что-то пропустил - добавляйте. Буду только благодарен
Лучшие ответы (1)
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
08.09.2009, 21:36     Флаги форматирования и манипуляторы
Посмотрите здесь:

Манипуляторы и флаги формата C++
C++ манипуляторы
манипуляторы C++
Манипуляторы C++
Манипуляторы. От С к С++ C++
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Evg
Эксперт С++Автор FAQ
 Аватар для Evg
16824 / 5245 / 319
Регистрация: 30.03.2009
Сообщений: 14,121
Записей в блоге: 26
24.06.2012, 16:31     Флаги форматирования и манипуляторы #41
Цитата Сообщение от grizlik78 Посмотреть сообщение
Evg, да
Пичалька...
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
ForEveR
Модератор
Эксперт C++
 Аватар для ForEveR
7927 / 4709 / 318
Регистрация: 24.06.2010
Сообщений: 10,524
Завершенные тесты: 3
24.06.2012, 16:33     Флаги форматирования и манипуляторы #42
Создание (вернее, внедрение) манипулятора сообщение №2
grizlik78
Эксперт C++
 Аватар для grizlik78
1882 / 1414 / 101
Регистрация: 29.05.2011
Сообщений: 2,958
24.06.2012, 16:44     Флаги форматирования и манипуляторы #43
Цитата Сообщение от grizlik78 Посмотреть сообщение
свой потоковый класс, на использование которого, кстати, можно переключать с использованием своего манипулятора. Кажется
Эх, размечтался я... Фиг чего сделаешь полезного пользовательскими манипуляторами стандартным путём.
Evg
Эксперт С++Автор FAQ
 Аватар для Evg
16824 / 5245 / 319
Регистрация: 30.03.2009
Сообщений: 14,121
Записей в блоге: 26
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-ричного представления всегда относится к беззнаковому)
grizlik78
Эксперт C++
 Аватар для grizlik78
1882 / 1414 / 101
Регистрация: 29.05.2011
Сообщений: 2,958
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;
}
Если кто знает методы проще — предлагайте.
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
16.10.2012, 21:36     Флаги форматирования и манипуляторы
Еще ссылки по теме:

C++ Манипуляторы ввода-вывода. Флаги
C++ Флаги форматирования в cout, выравнивание справа
Флаги форматирования cout C++

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

Или воспользуйтесь поиском по форуму:
Evg
Эксперт С++Автор FAQ
 Аватар для Evg
16824 / 5245 / 319
Регистрация: 30.03.2009
Сообщений: 14,121
Записей в блоге: 26
16.10.2012, 21:36     Флаги форматирования и манипуляторы #46
Своё видение по способу изложения материала поместил сюда: http://www.cyberforum.ru/blogs/18334/blog507.html
Yandex
Объявления
16.10.2012, 21:36     Флаги форматирования и манипуляторы
Ответ Создать тему

Метки
Манипуляторы, с++, Флаги форматирования
Опции темы

Текущее время: 11:49. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru