2 / 2 / 0
Регистрация: 01.10.2016
Сообщений: 63
1

Создание манипулятора

01.07.2017, 14:24. Показов 2422. Ответов 28
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Как создать манипулятор, преобразующий массив символов при выводе из потока в массив тех же символов, но уже верхнего регистра? Например
C++
1
cout << up << "кибер";
Должно быть выведено "КИБЕР".
0
Лучшие ответы (1)
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
01.07.2017, 14:24
Ответы с готовыми решениями:

Создание (вернее, внедрение) манипулятора
Здравствуйте! Помогите пожалуйста! Лаба горит! Помогите создать манипулятор консольного...

Использование манипулятора setprecision
Какой вариант более правильный. Вычислить значение выражения, включающего 5 членов:...

Объясните значение манипулятора: формат с фиксированной точкой
Изучаю с++, начал недавно, выучил только типы данных. Наткнулся на непонятный мне момент. Кто может...

Создание 3D модели манипулятора
Здравствуйте, столкнулся с задачей которую не понимаю как решить :wall: Есть 3х мерная модель...

28
7793 / 6560 / 2984
Регистрация: 14.04.2014
Сообщений: 28,672
01.07.2017, 18:15 2
Манипулятором такое не сделать.
1
2 / 2 / 0
Регистрация: 01.10.2016
Сообщений: 63
01.07.2017, 18:22  [ТС] 3
Каково же тогда решение? Функции из подключаемых библиотек (string) использовать, вероятно, нельзя.
0
1494 / 1209 / 821
Регистрация: 29.02.2016
Сообщений: 3,614
01.07.2017, 20:31 4
Цитата Сообщение от Букер Посмотреть сообщение
(string) использовать, вероятно, нельзя.
тогда ассемблер
https://stackoverflow.com/ques... lize-words
0
7793 / 6560 / 2984
Регистрация: 14.04.2014
Сообщений: 28,672
01.07.2017, 21:27 5
Цитата Сообщение от Букер Посмотреть сообщение
Функции из подключаемых библиотек (string) использовать, вероятно, нельзя.
Для кого вероятно?
0
Эксперт С++
8739 / 4317 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
01.07.2017, 21:35 6
Цитата Сообщение от Букер Посмотреть сообщение
Как создать манипулятор
в "чистом виде" - никак.
поскольку стандартные std::basic_ostream
подобный функционал не поддерживает.

Цитата Сообщение от Букер Посмотреть сообщение
Каково же тогда решение?
раз стандартный стрим из коробки не умеет,
значит нужно подменить его нашим стримом.

http://rextester.com/CYRX36158

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
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
// =======================================================================
// =======================================================================
// =======================================================================
 
#include <locale>
 
namespace tools{
 
#if defined(__GNUC__) || defined(__MINGW32__) || defined(__MINGW__)
    #pragma GCC diagnostic push
    #pragma GCC diagnostic ignored "-Wctor-dtor-privacy"
#endif
 
    template<class str> class string_semantic
    {
        using s = ::std::remove_reference_t<str>;
 
        template<class u> static std::true_type
            check(decltype(&u::c_str)*);
 
        template<class> static std::false_type
            check(...);
 
        using checked     
            = decltype(check<s>(nullptr));
 
        enum { eIS_STRING  = checked::value            };
        enum { eIS_ARRAY   = std::is_array<s>::value   };
        enum { eIS_POINTER = std::is_pointer<s>::value };
    public:
        enum { value = eIS_STRING || eIS_ARRAY || eIS_POINTER };
    };
 
#if defined(__GNUC__) || defined(__MINGW32__) || defined(__MINGW__)
    #pragma GCC diagnostic pop
#endif
 
    #define dIF_STRING_SEMANTIC(type_)     \
        ::std::enable_if_t<::tools::string_semantic<type_>::value>* = nullptr
    #define dIF_NOT_STRING_SEMANTIC(type_) \
        ::std::enable_if_t<!::tools::string_semantic<type_>::value>* = nullptr
 
}// namespace tools
 
// =======================================================================
// =======================================================================
// =======================================================================
 
#include <iostream>
 
struct wrap_cout
{
    using manipulator
        = std::wostream&(*)(std::wostream&);
 
    using wrap_manipulator
        = wrap_cout&(*)(wrap_cout&);
 
    wrap_cout(std::wostream& os)
        : os(os), upcase(false)
    {}
    
    template<class T, dIF_STRING_SEMANTIC(T)>
    wrap_cout& operator<< (T&& data) 
    { 
        if(!upcase)
            os << data; 
        else
        {
            std::locale loc("");
            for (auto& ch: data) 
                os << ::std::toupper(ch, loc);
        }
        return *this;
    }
 
    template<class T, dIF_NOT_STRING_SEMANTIC(T)>
    wrap_cout& operator<< (T&& data) 
    { 
        os << std::forward<T>(data); 
        return *this;
    }
 
    wrap_cout& operator<< (manipulator func)
        { func(os); return *this; }
 
    void set_upacase(){ upcase = true;}
private:
    std::wostream& os;
    bool upcase;
};
 
 
wrap_cout& up(wrap_cout& out) 
{
    out.set_upacase();
    return out;
}
 
wrap_cout operator << (std::wostream& out, wrap_cout::wrap_manipulator func)
{
    wrap_cout o(out);
    return func(o); 
}
 
int main()
{
    ::setlocale(LC_ALL, "");
    std::wcout << up << L"кибер\n";
}
на что тут можно обратить внимание?

1.
с++ не осилил локали.
способ работает для английских буковок
для национальных символов - не гарантируется.

2.
решение использует паттерн "прокси".
то бишь, это не попытка подсунуть манипулятор для стандартного std::wostream
это - подмена самого std::wostream на обертку wrap_cout,
которая реализует дополнительный функционал под ваши хотелки,
и уже только потом делегирует стандартному std::wostream задачу по выводу данных.
1
nmcf
01.07.2017, 21:38
  #7

Не по теме:

Познавательно, конечно, но проще преобразовать строку в нужный регистр.

0
Эксперт С++
8739 / 4317 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
01.07.2017, 21:46 8
Цитата Сообщение от nmcf Посмотреть сообщение
но проще преобразовать строку в нужный регистр.
то бишь, вас не смущает тот факт,
что с++ такое в принципе до сих пор не умеет?

а то может покажете примерчик кодом,
как это можно провернуть для национальных символов?

кроссплатформенно, разумеется.
0
Неэпический
17870 / 10635 / 2054
Регистрация: 27.09.2012
Сообщений: 26,737
Записей в блоге: 1
01.07.2017, 21:56 9
Лучший ответ Сообщение было отмечено Букер как решение

Решение

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
//g++  5.4.0
#include <iostream>
#include <string>
#include <exception>
 
 
struct upper{
    upper() : stream(nullptr) {}
    upper(std::ostream &s) : stream(&s) {}
    std::ostream *stream; 
};
 
 
upper operator<<(std::ostream &s, const upper &)
{
    return {s};
}
 
 
 
std::ostream &operator<<(const upper &s, const char *source)
{
    if (s.stream == nullptr) {
        throw std::runtime_error("streami nvalid");
    }
    std::string str(source);
    if (!str.empty()) {
        auto& f = std::use_facet<std::ctype<char>>(s.stream->getloc());
        f.toupper(&str[0], &str[0] + str.size());
    }    
    return *s.stream << str;
}
 
 
 
int main()
{
    upper up;
    std::cout << up << "text";
}
http://rextester.com/ZCWHRE24918

Для кириллицы нужно дополнительное колдовство.
1
Эксперт С++
8739 / 4317 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
01.07.2017, 22:03 10
Цитата Сообщение от Croessmah Посмотреть сообщение
std::cout << up << "text";
Цитата Сообщение от Букер Посмотреть сообщение
cout << up << "кибер";
uppsss...

http://rextester.com/XAJS74362

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
//g++  5.4.0
 
#include <iostream>
 
 
 
struct upper{
    upper() : stream(nullptr) {}
    upper(std::ostream &s) : stream(&s) {}
    std::ostream *stream; 
};
 
 
upper operator<<(std::ostream &s, const upper &)
{
    return {s};
}
 
 
 
std::ostream &operator<<(const upper &s, const char *source)
{
    std::string str(source);
    if (!str.empty() && s.stream != nullptr) {
        auto& f = std::use_facet<std::ctype<char>>(s.stream->getloc());
        f.toupper(&str[0], &str[0] + str.size());
    }    
    return *s.stream << str;
}
 
 
 
int main()
{
    upper up;
    std::cout << up << "кибер";
}
Добавлено через 4 минуты

Не по теме:

Цитата Сообщение от Croessmah Посмотреть сообщение
Для кириллицы нужно дополнительное колдовство.
вот так всегда...
на самом интересном месте...

1
Неэпический
17870 / 10635 / 2054
Регистрация: 27.09.2012
Сообщений: 26,737
Записей в блоге: 1
01.07.2017, 22:03 11
Цитата Сообщение от hoggy Посмотреть сообщение
uppsss...
И? Я уже писал, что для кириллицы нужно будет колдовать.
0
Эксперт С++
8385 / 6147 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
01.07.2017, 22:11 12
Цитата Сообщение от hoggy Посмотреть сообщение
как это можно провернуть для национальных символов?
кроссплатформенно, разумеется.
И без icu, Qt ...
0
7793 / 6560 / 2984
Регистрация: 14.04.2014
Сообщений: 28,672
01.07.2017, 22:15 13
А что не так с кириллицей? Локаль же есть.
0
Эксперт С++
8385 / 6147 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
01.07.2017, 22:15 14
Букер, Если задание учебное "лишь бы сдать" то тупо "вписать кириллический алфавит" и сделать свою ф-ци toUpper() по нему..
а потом собственно манипулятор.
0
Неэпический
17870 / 10635 / 2054
Регистрация: 27.09.2012
Сообщений: 26,737
Записей в блоге: 1
01.07.2017, 22:17 15
Цитата Сообщение от hoggy Посмотреть сообщение
на самом интересном месте...
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
//g++  5.4.0
#include <iostream>
#include <string>
#include <exception>
 
 
#include <boost/locale.hpp>
#include <boost/algorithm/string/case_conv.hpp>
    
 
 
struct upper{
    upper() = default;
    upper(std::ostream &s) : stream(std::make_unique<std::ostream>(s.rdbuf())) {
        boost::locale::generator gen;
        std::locale loc = gen("ru_RU.UTF-8"); 
        stream->imbue(loc);
    }
    std::unique_ptr<std::ostream> stream; 
};
 
 
upper operator<<(std::ostream &s, const upper &)
{
    return {s};
}
 
 
 
std::ostream &operator<<(const upper &s, const char *source)
{
    if (!s.stream) {
        throw std::runtime_error("invalid stream");
    }
    return *s.stream << boost::locale::to_upper(source, s.stream->getloc());
}
 
 
 
int main()
{
    upper up;
    
    std::cout << up << "Для hoggy";
}
http://rextester.com/NOCV18199
1
Эксперт С++
8385 / 6147 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
01.07.2017, 22:20 16
Цитата Сообщение от Croessmah Посмотреть сообщение
std::locale loc = gen("ru_RU.UTF-8");
А под виндой прокатит?!
0
Эксперт С++
8739 / 4317 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
01.07.2017, 22:26 17
Цитата Сообщение от Croessmah Посмотреть сообщение
#include <boost/locale.hpp>
гм...

крутяк, чо!
0
Неэпический
17870 / 10635 / 2054
Регистрация: 27.09.2012
Сообщений: 26,737
Записей в блоге: 1
01.07.2017, 23:09 18
Цитата Сообщение от Avazart Посмотреть сообщение
А под виндой прокатит?!
В таком виде точно нет. Да и в винде с консолью не особо дела обстоят.
0
Эксперт С++
8739 / 4317 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
01.07.2017, 23:18 19
Цитата Сообщение от Croessmah Посмотреть сообщение
Да и в винде с консолью не особо дела обстоят.
в студии русская локаль из коробки поддерживается.
0
Эксперт С++
8385 / 6147 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
01.07.2017, 23:19 20
Цитата Сообщение от Croessmah Посмотреть сообщение
В таком виде точно нет. Да и в винде с консолью не особо дела обстоят.
При чем тут консоль?
Я про локаль "ru_RU.UTF-8"
0
01.07.2017, 23:19
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
01.07.2017, 23:19
Помогаю со студенческими работами здесь

Создание адресного манипулятора
Всем здравствуйте! Пишу уже не одни сутки манипулятор. Сегодня не могу избавиться от одной...

Создание графических изображений с помощью манипулятора мыши
Здравствуйте! У меня тема задания по Си такая: Создание графических изображений с помощью...

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

Питание манипулятора
Имеем 7 осевой манипулятор где есть 5 MG996R 2.5A 6V сервоприводов и два MG90S 4.8-6v, допустим...


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

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

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru