Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  
 
 
Рейтинг 4.89/9: Рейтинг темы: голосов - 9, средняя оценка - 4.89
0 / 0 / 0
Регистрация: 19.03.2022
Сообщений: 57

Манипулятор setw и метод ввода строки getline

05.09.2022, 22:24. Показов 2626. Ответов 33

Студворк — интернет-сервис помощи студентам
Всем доброго времени суток! Столкнулся со следующей проблемой.
Задача в "двух словах". Необходимо создать структуру, характеризующую работника, одним из полей которой имеется имя типа std::string. Далее создается массив структур в цикле, когда пользователь прекращает ввод, структуры из массива должны выводиться в консоль в виде таблицы.
Для структуры я решил перегрузить ввод и вывод. Собственно, ниже код:
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
#include <algorithm>
#include <cstddef>
#include <iomanip>
#include <iostream>
#include <iterator>
#include <string>
#include <vector>
 
struct Employee {
    std::size_t m_personnel_number{}; std::size_t m_shop_number{};
    std::string m_name{};
    std::size_t m_wade{};
    static std::size_t s_number;
 
    Employee() { ++s_number; }
 
    friend std::istream& operator>>(std::istream& in, Employee& employee) {
        std::cout << "Enter the pesonnel number of employee whith number " << employee.s_number << ": ";
        in >> employee.m_personnel_number;
        std::cout << "Enter the plant shop number: ";
        in >> employee.m_shop_number;
        std::cout << "Enter the name of employee: ";
        in >> employee.m_name;
        //std::getline(in, employee.m_name);
        std::cout << "Enter the wade of employee: ";
        in >> employee.m_wade;
        return in;
    }
 
    friend std::ostream& operator<<(std::ostream& out, const Employee& employee) {
        out << std::setw(128) << std::setfill('-') << '\n' << std::setfill(' ') 
 
            << "|" << std::setw(3) << "N" << std::setw(3) << "|"
            << std::setw(22) << "the personnel number" << std::setw(3) << "|"
            << std::setw(22) << "the plant shop number" << std::setw(3) << "|"
            << std::setw(32) << "the name of employee" << std::setw(13) << "|"
            << std::setw(22) << "the wade of employee" << std::setw(3) << "|" << '\n'
 
            << std::setw(128) << std::setfill('-') << '\n' << std::setfill(' ')
//после этого не получается
            << "|" << std::setw(3) << std::left << employee.s_number << std::setw(3) << "|"
            << std::setw(22) << std::left << employee.m_personnel_number << std::setw(3) << "|" 
            << std::setw(22) << std::left << employee.m_shop_number << std::setw(3) << "|" 
            << std::setw(22) << std::left << employee.m_name << std::setw(3) << "|" 
            << std::setw(22) << std::left << employee.m_wade << std::setw(3) << "|" << '\n' 
 
            << std::setw(128) << std::setfill('-') << '\n' << std::setfill(' ');
 
        return out;
    }
};
Проблемы следующие:
1. Как в перегрузке оператора ввода сделать так, чтобы при вводе имени можно было разделять пробелом имя и фамилию? В моем варианте просто при вводе структуры ничего не вводится или только первая часть до пробела, а если ввод в цикле, то происходит зацикливание, пробовал std::getline, но не помогает.
2. При перегрузке оператора вывода не могу выровнять таблицу, по какой-то причине не добавляются отступы перед s_number.
Прошу разъяснить, что не правильно, а также как исправить.
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
05.09.2022, 22:24
Ответы с готовыми решениями:

Setw() манипулятор
Проблема в том, что не могу разобраться как правильно отформатировать свою результат, хочу вывести значения, в виде таблицы. Вот код: ...

Не работает манипулятор setw(n)
Здравствуйте, написал маленькую программку по разделу из книги, чтобы лучше понять как работает манипулятор setw(n), однако при компиляции...

манипулятор ввода
написать любую программу, на манипулятор ввода

33
0 / 0 / 0
Регистрация: 19.03.2022
Сообщений: 57
07.09.2022, 10:26  [ТС]
Студворк — интернет-сервис помощи студентам
Цитата Сообщение от SmallEvil Посмотреть сообщение
стоит выделить часто используемые текстовые представления в именованные переменные
А как это сделать и как в дальнейшем эти переменные применять?
Цитата Сообщение от Алексей1153 Посмотреть сообщение
копим вектор векторов строк (таблица), затем для каждой колонки считаем максимальную ширину. При распечатке таблицы под эту ширину подгонять элементы пробелами или тем же setw
Блин, что-то тяжеловато. В лоб манипуляторами мне кажется проще, я хоть понимаю, что будет, или, по крайней мере, что должно быть...
0
 Аватар для SmallEvil
4086 / 2975 / 813
Регистрация: 29.06.2020
Сообщений: 11,000
07.09.2022, 10:30
И в догоночку, завести константу для количества символов в строке и воспользоваться совета кота Алексея (в общих чертах).
Ибо я даже не могу протестировать ваш код, в 128 символов ))
0
фрилансер
 Аватар для Алексей1153
6495 / 5726 / 1133
Регистрация: 11.10.2019
Сообщений: 15,286
07.09.2022, 10:31
Цитата Сообщение от Shimon Посмотреть сообщение
В лоб манипуляторами мне кажется проще
заранее длина строки всё равно неизвестна. В общем случае может получиться неожиданный сдвиг
0
 Аватар для SmallEvil
4086 / 2975 / 813
Регистрация: 29.06.2020
Сообщений: 11,000
07.09.2022, 10:31
Shimon, если пока сложно то попробуй printf.
Легче не будет, но там вывод корректируется четче.
Чисто как вариант
0
0 / 0 / 0
Регистрация: 19.03.2022
Сообщений: 57
07.09.2022, 10:35  [ТС]
Цитата Сообщение от John Prick Посмотреть сообщение
Так а с чего он возьмётся? Вы ставите выравнивание по левому краю.
Если я не ошибаюсь, по дефолту выравнивание по правому краю, если применяется setw. В шапке отступы между границами столбцов и содержимым имеются.
В моем понимании я ввожу границу, дальше выравнивание по левому краю, дальше отступ от предыдущего символа (границы) до следующего (содержимого). Но что-то не работает, значит ошибка в моих рассуждениях, но пока не втыкаю, в чем.

Добавлено через 3 минуты
Цитата Сообщение от SmallEvil Посмотреть сообщение
И в догоночку, завести константу для количества символов в строке и воспользоваться совета кота Алексея (в общих чертах).
Ибо я даже не могу протестировать ваш код, в 128 символов ))
Спасибо за совет, но я не догоняю, как это реализовать...
0
 Аватар для SmallEvil
4086 / 2975 / 813
Регистрация: 29.06.2020
Сообщений: 11,000
07.09.2022, 10:35
Цитата Сообщение от Shimon Посмотреть сообщение
А как это сделать и как в дальнейшем эти переменные применять?
Вот вот. Вот так.
C++
1
2
3
const int SWidth = 128;
const int Main_tab = 22;
// ...
Тогда можно настроить на любую ширину символов в консоли и проверить.
А так куча непонятных циферок, и что мне с ними делать ? Если в моей консоли 80 символов в ряду.
Да и жесткие отступы также излишние. Делайте резиновую таблицу. Один раз сделали, и копипастите оттуда нужные части.
p.s. Я давно уже таким не играюсь ...
0
0 / 0 / 0
Регистрация: 19.03.2022
Сообщений: 57
07.09.2022, 10:37  [ТС]
Цитата Сообщение от SmallEvil Посмотреть сообщение
попробуй printf.
Ни разу не пользовался printf, только объектами потоков... Буду, наверное, дальше равнять манипуляторами...
0
2405 / 1937 / 763
Регистрация: 27.07.2012
Сообщений: 5,576
07.09.2022, 10:37
Цитата Сообщение от Shimon Посмотреть сообщение
Если я не ошибаюсь
Если вы про этот код:
C++
1
std::cout << "|" << std::left << std::setw(22) << "100500\n";
то ошибаетесь
Цитата Сообщение от Shimon Посмотреть сообщение
В моем понимании я ввожу границу,
"|" ОК
Цитата Сообщение от Shimon Посмотреть сообщение
дальше выравнивание по левому краю
std::left ОК
Цитата Сообщение от Shimon Посмотреть сообщение
дальше отступ от предыдущего символа (границы) до следующего (содержимого)
std::setw(22) FAIL. Это не отступ, а ширина следующего содержимого. Далее у вас выведется "100500" и 22 - strlen("100500") пробелов.
0
0 / 0 / 0
Регистрация: 19.03.2022
Сообщений: 57
07.09.2022, 10:38  [ТС]
Цитата Сообщение от SmallEvil Посмотреть сообщение
попробуй printf.
Ни разу не пользовался printf, только объектами потоков... Буду, наверное, дальше равнять манипуляторами...
0
 Аватар для SmallEvil
4086 / 2975 / 813
Регистрация: 29.06.2020
Сообщений: 11,000
07.09.2022, 10:46
Ну епическая сила ...
Цитата Сообщение от SmallEvil Посмотреть сообщение
std::cout << "|" << std::right << std::setw(22) << "100500\n";
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
#include <algorithm>
#include <cstddef>
#include <iomanip>
#include <iostream>
#include <iterator>
#include <string>
#include <vector>
 
 
struct Employee {
    std::size_t m_personnel_number{}; std::size_t m_shop_number{};
    std::string m_name{};
    std::size_t m_wade{};
    static std::size_t s_number;
 
    Employee() { ++s_number; }
 
    friend std::istream& operator>>(std::istream& in, Employee& employee) {
        std::cout << "Enter the pesonnel number of employee whith number " << employee.s_number << ": ";
        in >> employee.m_personnel_number;
        std::cout << "Enter the plant shop number: ";
        in >> employee.m_shop_number;
        std::cout << "Enter the name of employee: ";
        in.ignore(32767, '\n');
        std::getline(in, employee.m_name);
        std::cout << "Enter the wade of employee: ";
        in >> employee.m_wade;
        return in;
    }
 
    friend std::ostream& operator<<(std::ostream& out, const Employee& employee) {
        out << std::setw(128) << std::setfill('-') << '\n' << std::setfill(' ') 
 
            << "|" << std::setw(3) << "N" << std::setw(3) << "|"
            << std::setw(22) << "the personnel number" << std::setw(3) << "|"
            << std::setw(22) << "the plant shop number" << std::setw(3) << "|"
            << std::setw(32) << "the name of employee" << std::setw(13) << "|"
            << std::setw(22) << "the wade of employee" << std::setw(3) << "|" << '\n'
 
            << std::setw(128) << std::setfill('-') << '\n' << std::setfill(' ')
 
            << "|" << std::setw(3) << std::right << employee.s_number << std::setw(3) << "|"
            << std::setw(22) << std::left << employee.m_personnel_number << std::setw(3) << "|" 
            << std::setw(22) << std::left << employee.m_shop_number << std::setw(3) << "|" 
            << std::setw(22) << std::left << employee.m_name << std::setw(3) << "|" 
            << std::setw(22) << std::left << employee.m_wade << std::setw(3) << "|" << '\n' 
 
            << std::setw(128) << std::setfill('-') << '\n' << std::setfill(' ');
 
        return out;
    }
 
};
 
std::size_t Employee::s_number{0};
 
int main() {
    std::vector<Employee> array_of_employees{};
    char flag{'y'};
    while(flag == 'y') {
        Employee employee;
        std::cin >> employee;
        array_of_employees.push_back(employee);
        std::cout << "Will yor enter the data? (y or n)";
        std::cin >> flag;
    }
 
    std::copy(std::begin(array_of_employees), std::end(array_of_employees), std::ostream_iterator<Employee>{std::cout, "\n"});
    std::cout << '\n';
}
Добавлено через 1 минуту
Цитата Сообщение от Shimon Посмотреть сообщение
Ни разу не пользовался printf
Тогда и не надо пока, там свои заморочки с форматами, в первый раз давались очень тяжело.

Добавлено через 3 минуты
Shimon, и если просто нужен фиксированный отступ :
C++
1
cout << "|   ";
Все !

Добавлено через 3 минуты
Ах да, про именование часто использованных отступов.
C++
1
2
3
    const std::string Tab_Space_3(3, ' ');
    const char DELIM1 = '|';
    std::cout << DELIM1<<Tab_Space_3;
*_*
0
0 / 0 / 0
Регистрация: 19.03.2022
Сообщений: 57
07.09.2022, 10:50  [ТС]
Цитата Сообщение от John Prick Посмотреть сообщение
Это не отступ, а ширина следующего содержимого.
опа, а вот тут-то я и ошибался)))

Цитата Сообщение от SmallEvil Посмотреть сообщение
Ну епическая сила ...
В своем я поменял местами манипуляторы)))
Буду исправлять, потом отпишу, что получится...
0
0 / 0 / 0
Регистрация: 19.03.2022
Сообщений: 57
07.09.2022, 11:07  [ТС]
Докладываю о промежуточных результатах...
Вот код по заполнению строк:
C++
1
2
3
4
5
6
out << "|  " << std::left << std::setw(22) << worker.m_personnel_number << std::setw(3) << "|" 
                << std::left << std::setw(22) << worker.m_shop_number << std::setw(3) << "|" 
                << std::left << std::setw(42) << worker.m_name << std::setw(3) << "|" 
                << std::left << std::setw(23) << worker.m_salary << "|" << '\n'
 
                << std::setw(123) << std::setfill('-') << '\n' << std::setfill(' ');
Прикрепляю скрин того, что получилось. Вроде бы выровнял, но откуда-то берется лишний перевод строки перед нижней границей строки таблицы. В шапке такой же код, но не добавляет перевод строки...
Миниатюры
Манипулятор setw и метод ввода строки getline  
0
2405 / 1937 / 763
Регистрация: 27.07.2012
Сообщений: 5,576
07.09.2022, 12:25
Цитата Сообщение от Shimon Посмотреть сообщение
Вроде бы выровнял, но откуда-то берется лишний перевод строки перед нижней границей строки таблицы.
Потому что вы его выводите
Строку с чертой можно вывести проще: std::cout << std::string(123, '-');
0
0 / 0 / 0
Регистрация: 19.03.2022
Сообщений: 57
07.09.2022, 17:07  [ТС]
Вроде бы все получилось, ну, по крайней мере, пока содержимое меньше ширины столбца. Скрин прикрепляю.
Но какое-то топорное решение...
[
quote="Алексей1153;16437546"]копим вектор векторов строк (таблица), затем для каждой колонки считаем максимальную ширину. При распечатке таблицы под эту ширину подгонять элементы пробелами или тем же setw[/quote]

А не могли бы поподробнее изложить суть? Что у меня должно храниться в векторах-"строках таблицы" и как потом это выводить с учетом заполнения?
Миниатюры
Манипулятор setw и метод ввода строки getline  
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
07.09.2022, 17:07

Манипулятор ввода / вывода
Чем отличается манипулятор ввода\вывода от пользовательский ввод\вывод ?

There are no arguments to 'setw' that depend on a template parameter, so a declaration of 'setw' must be available
void throw_if_less_zero(int value) { if (value &lt; 0) throw new out_of_range(&quot;value должно быть неотрицательным&quot;); } ...

Написать программу «Манипулятор робота» так, чтобы она рисовала манипулятор из n сегментов
Здравствуйте)). Прошу помочь. Написать программу «Манипулятор робота» так, чтобы она рисовала манипулятор из n сегментов. Для...

Манипулятор ввода, который поочередно то считывает, то пропускает каждые десять символов
Задание звучит так: Вот что я уже сделал: istream&amp; skipchar(istream&amp; stream) { for (int i = 0; i &lt; 10; i++) { ...

Неправильный вывод UTF8 строки вместе с setw
Есть файл с UTF8 строкой. Считываем его и выводим во второй файл с выравниванием. В результате выравнивание нету. Почему так? Чем...


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

Или воспользуйтесь поиском по форуму:
34
Ответ Создать тему
Новые блоги и статьи
сукцессия 29. Переход от одних деревьев на другие делать более или менее вероятностным?
anaschu 12.07.2026
Насколько смена типов микоризы — исключительное событие в двухвековой сукцессии? Оценка вероятности в пространстве параметров В текущей версии модели успешно реализован ключевой механизм. . .
сукцессия 27. Думаю, как переделывать уже написанную статью с планами на сукцессию.
anaschu 12.07.2026
Анализ соответствия модели требованиям Реализованные компоненты: Механизм закисления почвы через протонную помпу Конкуренция между типами микориз pH как триггер сукцессии C/ P соотношение. . .
Сукцессия 26. Мат модель создана.
anaschu 12.07.2026
Модель смены растительных сукцессий посредством управления грибами работает внутри небольшой ячейки почвы, восстанавливающейся после пожара, где ненадолго бывшее царство хвойных снова захватили. . .
Решил проблему с ошибкой пагинации сообщений с сервера на алгоритме обхода дерева "Эстафета хвоста".
Hrethgir 12.07.2026
Проблема была в том, что удалялась именно новая кнопка, а не старая. Ни один ИИ не обнаружил это, а сам я смог только когда с работой стало попроще и когда заставил работать будущее автономное. . .
сукцессия 25. Хронология ошибок
anaschu 12.07.2026
# От 50-тонного гриба до устойчивого леса: хроника ошибок при построении модели вековой сукцессии микоризы ## О чём эта статья В процессе построения ОДУ-модели (система дифференциальных. . .
сукцессия 24. Промежуточное общее описание модели
anaschu 12.07.2026
Хендофф: модель АМ→ЭКМ сукцессии микоризы (ризосфера, 50 лет) Содержание проекта Симуляция вековой (50 лет) экологической сукцессии в почве леса Основные участники: АМ-гриб, ЭКМ-гриб,. . .
сукцессия 23. Более физиологичная физиология, более экологичная экология, более диффурные диффуры.
anaschu 12.07.2026
Что реально нашли и починили за эти 5 часов Правило Линдемана (КПД конверсии сахара в тело, kEff) — раньше 100% полученного углерода шло прямо в биомассу гриба; теперь только kEff=0. 5 (после. . .
сукцессия 22. От артефактов к физиологии: калибровка агентной модели грибной сукцессии для воспроизведения сезонной динамики и pH-плато
anaschu 11.07.2026
Аннотация В данной работе представлена калибровка агентной модели динамики грибных сообществ (fungal-succession), направленная на устранение нефизичных артефактов (коллапс биомассы, мгновенное. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru