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

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

05.09.2022, 22:24. Показов 2346. Ответов 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
фрилансер
 Аватар для Алексей1153
6444 / 5637 / 1128
Регистрация: 11.10.2019
Сообщений: 14,997
05.09.2022, 23:20
Shimon, приведи полный код
0
Заблокирован
05.09.2022, 23:38
Цитата Сообщение от Shimon Посмотреть сообщение
пробовал std::getline, но не помогает
Не помогает потому что могут оставаться управляющие символы (пробел, перенос строки и так далее), после ввода чисел.
1
0 / 0 / 0
Регистрация: 19.03.2022
Сообщений: 57
06.09.2022, 09:53  [ТС]
Цитата Сообщение от SmallEvil Посмотреть сообщение
могут оставаться управляющие символы (пробел, перенос строки и так далее), после ввода чисел.
Согласен, упустил этот момент. Добавил строчку кода - помогло.

Добавлено через 5 минут
Цитата Сообщение от Алексей1153 Посмотреть сообщение
приведи полный код
Привожу код, который я написал, косяк с вводом имени исправил.
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::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;
    }
 
};
 
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';
}
По выводу таблицы косяк какой-то в выравнивании что ли, не добавляет setw требуемых отступов. Ну и для каждого члена структуры выводит шапку, так как я ее в перегрузку впихнул...
0
2393 / 1913 / 763
Регистрация: 27.07.2012
Сообщений: 5,557
06.09.2022, 11:52
Цитата Сообщение от Shimon Посмотреть сообщение
По выводу таблицы косяк какой-то в выравнивании что ли, не добавляет setw требуемых отступов.
Ну так у вас в шапке << std::setw(32) << "the name of employee" << std::setw(13) << "|". т.е. 32 + 13 = 45, а в выводе значения << std::setw(22) << std::left << employee.m_name << std::setw(3) << "|" - 22 + 3 = 25.

Но всё равно всё это хозяйство в консоль не влезет.
0
0 / 0 / 0
Регистрация: 19.03.2022
Сообщений: 57
06.09.2022, 11:56  [ТС]
Цитата Сообщение от John Prick Посмотреть сообщение
всё это хозяйство в консоль не влезет.
Как раз таки шапка таблицы нормально помещается, если консоль на полный экран. Вопрос возникает при заполнении полей таблицы: не могу выровнять,чтобы разделители столбцов шапки и строк совпадали. Setw не добавляет отступ от левой границы, похоже, что я не понимаю, учитывается ли длина строки в аргумент setw или нет
0
2393 / 1913 / 763
Регистрация: 27.07.2012
Сообщений: 5,557
06.09.2022, 12:18
Цитата Сообщение от Shimon Посмотреть сообщение
Setw не добавляет отступ от левой границы
C++
1
<< std::left << std::setw(22) << employee.m_name
setw действует только на следующий аргумент потока
0
Заблокирован
07.09.2022, 09:07
Цитата Сообщение от John Prick Посмотреть сообщение
setw действует только на следующий аргумент потока
То есть неважно даже что он управляющий ? забавно )
0
2393 / 1913 / 763
Регистрация: 27.07.2012
Сообщений: 5,557
07.09.2022, 09:27
Цитата Сообщение от SmallEvil Посмотреть сообщение
То есть неважно даже что он управляющий ? забавно )
Хотя не, почитал сейчас, ширина поля сбрасывается только после форматированного вывода, поэтому должен работать как cout << left << setw(22) << 100500, так и cout << setw(22) << left << 100500.
0
0 / 0 / 0
Регистрация: 19.03.2022
Сообщений: 57
07.09.2022, 09:48  [ТС]
Цитата Сообщение от John Prick Посмотреть сообщение
Хотя не, почитал сейчас, ширина поля сбрасывается только после форматированного вывода, поэтому должен работать как cout << left << setw(22) << 100500, так и cout << setw(22) << left << 100500.
Проверил, работает. Но как только вставить дополнительный символ, то между ними отступы не ставятся.
C++
1
2
std::cout << "|" << std::left << std::setw(22) << "100500\n";
std::cout << "|" << std::setw(22) << std::left << "100500\n";
Идея какая: необходимо вставить отступ между границей строки "|" и ее содержимым. И вот с этим проблема.
0
2393 / 1913 / 763
Регистрация: 27.07.2012
Сообщений: 5,557
07.09.2022, 10:03
Цитата Сообщение от Shimon Посмотреть сообщение
Но как только вставить дополнительный символ
Ну так про то и речь. Для каждого форматированного вывода (т.е. такого вывода, после которого что-то отобразится в консоли) ширина сбрасывается и её надо по новой ставить с помощью setw.

Добавлено через 1 минуту
Цитата Сообщение от Shimon Посмотреть сообщение
необходимо вставить отступ между границей строки "|" и ее содержимым
Где для строки "|" её граница, а где содержимое? Что-то не улавливаю терминологию. Приведите пример хоть, что выводит и что надо.
0
0 / 0 / 0
Регистрация: 19.03.2022
Сообщений: 57
07.09.2022, 10:07  [ТС]
Цитата Сообщение от John Prick Посмотреть сообщение
Приведите пример хоть, что выводит и что надо.
Я выше код скидывал, по которому проблемы, собственно, и сами проблемы по нему.
Но если точечно, то пример в посте выше: граница столбцов строки из символов "|", а содержимое "100500".
0
2393 / 1913 / 763
Регистрация: 27.07.2012
Сообщений: 5,557
07.09.2022, 10:10
Цитата Сообщение от Shimon Посмотреть сообщение
Я выше код скидывал, по которому проблемы
Не код, а что он выводит. И как вы хотите, чтобы выводил.
0
Заблокирован
07.09.2022, 10:16
Цитата Сообщение от Shimon Посмотреть сообщение
Идея какая: необходимо вставить отступ между границей строки "|" и ее содержимым. И вот с этим проблема.
Так и в чем проблема ?
C++
1
    std::cout << "|" << std::right << std::setw(22) << "100500\n";
0
0 / 0 / 0
Регистрация: 19.03.2022
Сообщений: 57
07.09.2022, 10:16  [ТС]
Цитата Сообщение от John Prick Посмотреть сообщение
Не код, а что он выводит.
Понял, не сообразил. Скрин ниже. Шапку кое как выровнял, и если честно, то не понял как. А вот строки не получается.
Миниатюры
Манипулятор setw и метод ввода строки getline  
0
Заблокирован
07.09.2022, 10:18
Shimon, и что бы это все форматирование имело смысл, стоит выделить часто используемые текстовые представления в именованные переменные (константные конечно, если нет веских нужд для их изменения)..
0
фрилансер
 Аватар для Алексей1153
6444 / 5637 / 1128
Регистрация: 11.10.2019
Сообщений: 14,997
07.09.2022, 10:18
Shimon, если по заданию нет ограничений на ОЗУ, то могу предложить такое решение:

копим вектор векторов строк (таблица), затем для каждой колонки считаем максимальную ширину. При распечатке таблицы под эту ширину подгонять элементы пробелами или тем же setw
0
0 / 0 / 0
Регистрация: 19.03.2022
Сообщений: 57
07.09.2022, 10:20  [ТС]
Цитата Сообщение от SmallEvil Посмотреть сообщение
Так и в чем проблема ?
Нету отступа между "|" и "100500". Скрин ниже.
Миниатюры
Манипулятор setw и метод ввода строки getline  
0
Заблокирован
07.09.2022, 10:20
Цитата Сообщение от Shimon Посмотреть сообщение
А вот строки не получается.
в строках минус два пробела в начале.
Ыть ?
0
2393 / 1913 / 763
Регистрация: 27.07.2012
Сообщений: 5,557
07.09.2022, 10:23
Цитата Сообщение от Shimon Посмотреть сообщение
Скрин ниже.
Ну так у вас после первой "|" не хватает двух пробелов, просто добавьте их к этой же строке. И сразу 2 колонки на место встанут.
После надо добавить в setw для поля имени, об этом я уже писал выше.

Добавлено через 1 минуту
Цитата Сообщение от Shimon Посмотреть сообщение
Нету отступа между "|" и "100500". Скрин ниже.
Так а с чего он возьмётся? Вы ставите выравнивание по левому краю.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
07.09.2022, 10:23
Помогаю со студенческими работами здесь

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

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 строкой. Считываем его и выводим во второй файл с выравниванием. В результате выравнивание нету. Почему так? Чем...


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

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Новые блоги и статьи
Thinkpad X220 Tablet — это лучший бюджетный ноутбук для учёбы, точка.
Programma_Boinc 23.12.2025
Thinkpad X220 Tablet — это лучший бюджетный ноутбук для учёбы, точка. Рецензия / Мнение/ Перевод https:/ / **********/ gallery/ thinkpad-x220-tablet-porn-gzoEAjs . . .
PhpStorm 2025.3: WSL Terminal всегда стартует в ~
and_y87 14.12.2025
PhpStorm 2025. 3: WSL Terminal всегда стартует в ~ (home), игнорируя директорию проекта Симптом: После обновления до PhpStorm 2025. 3 встроенный терминал WSL открывается в домашней директории. . .
Как объединить две одинаковые БД Access с разными данными
VikBal 11.12.2025
Помогите пожалуйста !! Как объединить 2 одинаковые БД Access с разными данными.
Новый ноутбук
volvo 07.12.2025
Всем привет. По скидке в "черную пятницу" взял себе новый ноутбук Lenovo ThinkBook 16 G7 на Амазоне: Ryzen 5 7533HS 64 Gb DDR5 1Tb NVMe 16" Full HD Display Win11 Pro
Музыка, написанная Искусственным Интеллектом
volvo 04.12.2025
Всем привет. Некоторое время назад меня заинтересовало, что уже умеет ИИ в плане написания музыки для песен, и, собственно, исполнения этих самых песен. Стихов у нас много, уже вышли 4 книги, еще 3. . .
От async/await к виртуальным потокам в Python
IndentationError 23.11.2025
Армин Ронахер поставил под сомнение async/ await. Создатель Flask заявляет: цветные функции - провал, виртуальные потоки - решение. Не threading-динозавры, а новое поколение лёгких потоков. Откат?. . .
Поиск "дружественных имён" СОМ портов
Argus19 22.11.2025
Поиск "дружественных имён" СОМ портов На странице: https:/ / norseev. ru/ 2018/ 01/ 04/ comportlist_windows/ нашёл схожую тему. Там приведён код на С++, который показывает только имена СОМ портов, типа,. . .
Сколько Государство потратило денег на меня, обеспечивая инсулином.
Programma_Boinc 20.11.2025
Сколько Государство потратило денег на меня, обеспечивая инсулином. Вот решила сделать интересный приблизительный подсчет, сколько государство потратило на меня денег на покупку инсулинов. . . .
Ломающие изменения в C#.NStar Alpha
Etyuhibosecyu 20.11.2025
Уже можно не только тестировать, но и пользоваться C#. NStar - писать оконные приложения, содержащие надписи, кнопки, текстовые поля и даже изображения, например, моя игра "Три в ряд" написана на этом. . .
Мысли в слух
kumehtar 18.11.2025
Кстати, совсем недавно имел разговор на тему медитаций с людьми. И обнаружил, что они вообще не понимают что такое медитация и зачем она нужна. Самые базовые вещи. Для них это - когда просто люди. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru