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

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

05.09.2022, 22:24. Показов 2336. Ответов 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
Заблокирован
07.09.2022, 10:30
И в догоночку, завести константу для количества символов в строке и воспользоваться совета кота Алексея (в общих чертах).
Ибо я даже не могу протестировать ваш код, в 128 символов ))
0
фрилансер
 Аватар для Алексей1153
6442 / 5636 / 1127
Регистрация: 11.10.2019
Сообщений: 14,982
07.09.2022, 10:31
Цитата Сообщение от Shimon Посмотреть сообщение
В лоб манипуляторами мне кажется проще
заранее длина строки всё равно неизвестна. В общем случае может получиться неожиданный сдвиг
0
Заблокирован
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
Заблокирован
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
2393 / 1913 / 763
Регистрация: 27.07.2012
Сообщений: 5,557
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
Заблокирован
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
2393 / 1913 / 763
Регистрация: 27.07.2012
Сообщений: 5,557
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
Ответ Создать тему
Новые блоги и статьи
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
Кстати, совсем недавно имел разговор на тему медитаций с людьми. И обнаружил, что они вообще не понимают что такое медитация и зачем она нужна. Самые базовые вещи. Для них это - когда просто люди. . .
Создание Single Page Application на фреймах
krapotkin 16.11.2025
Статья исключительно для начинающих. Подходы оригинальностью не блещут. В век Веб все очень привыкли к дизайну Single-Page-Application . Быстренько разберем подход "на фреймах". Мы делаем одну. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru