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

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
 
Exzotick
0 / 0 / 0
Регистрация: 25.05.2014
Сообщений: 25
#1

Возврат функцией массива структур - C++

27.05.2014, 17:39. Просмотров 745. Ответов 23
Метки нет (Все метки)

Пишу программу, которая в зависимости от выбора пользователя считывает информацию о студентах, вводимую с клавиатуры, либо использует заранее подготовленный массив. После этого сортирует массив и выводит таблицу в виде упорядоченного по группам и алфавиту списка. Проблема с использованием массива-заготовки. Как правильно передать его в функцию? И еще вопрос: вот у меня есть структура students, у нее поля name, group и др. Можно ли получить размер определенного поля структуры, не используя непосредственно переменных с этим структурным типом (т.е., я знаю, что, если student1 - переменная структурного типа students, можно написать "sizeof (student1.name)", а можно ли еще как-то)?
Кликните здесь для просмотра всего текста
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
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
//7.4
#include <iostream>
#include <algorithm>
#include <windows.h>
#include <cstring>
#include <iomanip>
//#include <cstdio>
using namespace std;
 
const int name_size = 30, n = 6;
struct students
{
    char name[name_size];
    char group[n];
    int age;
    float average;
    float scholarship;
};
 
students* fill_arr(int);
students* use_arr();
students  fill_name(students);
students  fill_group(students);
int fill_age(students);
float fill_average(students);
float fill_scholaship(students);
void print_data(students);
void print_data_tab(students);
 
int main()
{
    SetConsoleCP(1251);
    SetConsoleOutputCP(1251);
    char choice;
    students *students_arr = NULL;
    int students_num;
    cout << "Заполните информацию о студентах \n1-ввести данные с клавиатуры \n2-использовать заготовку" << endl;
    cin >> choice;
    switch (choice)
    {
    case '1':
        cout << "Введите количество студентов: ";
        cin >> students_num;
        students_arr = fill_arr(students_num);
        break;
    case '2':
        students_arr = use_arr();
        students_num = sizeof (students_arr) / sizeof (students);
        break;
    }
    system("cls");
    cout << "\nИнформация о студентах: \n" << endl;
    int i, j; students temp;
    for (i = 0; i < students_num; i++)
        for (j = 0; j<students_num - i - 1; j++)
            if (strcmp(students_arr[j].group, students_arr[j + 1].group) > 0)
                swap(students_arr[j], students_arr[j + 1]);
            else
            if (strcmp(students_arr[j].group, students_arr[j + 1].group) == 0)
                if (strcmp(students_arr[j].name, students_arr[j + 1].name) > 0)
                    swap(students_arr[j], students_arr[j + 1]);
    for (int i = 0; i < students_num; i++)
        print_data_tab(students_arr[i]);
    system("pause");
}
students* fill_arr(int students_num)
{
    students* students_arr = new students[students_num];
    for (int i = 0; i < students_num; i++)
    {
        students_arr[i] = fill_name(students_arr[i]);
        students_arr[i] = fill_group(students_arr[i]);
        students_arr[i].age = fill_age(students_arr[i]);
        students_arr[i].average = fill_average(students_arr[i]);
        students_arr[i].scholarship = fill_scholaship(students_arr[i]);
    }
    return students_arr;
}
students* use_arr()
{
    students student1 = { "Урманов Роман Сергеевич", "Б8120", 18, 5.0, 7500 },
        student2 = { "Спицын Вячеслав Валерьевич", "Б8120", 17, 4.5, 0 },
        student3 = { "Аристова Дарья Павловна", "Б8120", 18, 4.0, 0 },
        student4 = { "Иванов Петр Владимирович", "М6180", 22, 5.0, 9000 },
        student5 = { "Дорошин Сергей Александрович", "М6180", 22, 4.9, 2800 },
        student6 = { "Годенко Николай Борисович", "Б5216", 19, 4.3, 2400 },
        student7 = { "Афанасьев Виктор Иванович", "Б5216", 19, 4.0, 1900 },
        student8 = { "Галинов Вячеслав Иванович", "Б5216", 19, 3.8, 0 };
    students default_students_arr[] = { student1, student2, student3, student4, student5, student6, student7, student8 };
    return default_students_arr;
}
students  fill_name(students stu_data)
{
    cout << "\nВведите имя студента: ";
    cin.get();
    gets_s(stu_data.name, sizeof (stu_data.name));
    return stu_data;
}
students fill_group(students stu_data)
{
    cout << "Введите группу: ";
    gets_s(stu_data.group, sizeof (stu_data.group));
    return stu_data;
}
int fill_age(students stu_data)
{
    cout << "Введите возраст студента: ";
    cin >> stu_data.age;
    return stu_data.age;
}
float fill_average(students stu_data)
{
    cout << "Введите средний балл студента: ";
    cin >> stu_data.average;
    return stu_data.average;
}
float fill_scholaship(students stu_data)
{
    cout << "Введите размер стипендии: ";
    cin >> stu_data.scholarship;
    return stu_data.scholarship;
}
void print_data(students stu_data)
{
    cout << "ФИО студента: " << stu_data.name << endl
        << "Группа: " << stu_data.group << endl
        << "Возраст: " << stu_data.age << endl
        << "Средний балл: " << stu_data.average << endl
        << "Стипендия: " << stu_data.scholarship << endl << endl;
}
void print_data_tab(students stu_data)
{
    cout << setiosflags(ios::left) << setw(sizeof (stu_data.group)) << stu_data.group << setw(sizeof (stu_data.name)) << stu_data.name << setw(4) << stu_data.age << setw(5) << stu_data.average << setw(6) << stu_data.scholarship << endl;
}
Лучшие ответы (1)
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
27.05.2014, 17:39     Возврат функцией массива структур
Посмотрите здесь:

Сортировка элементов массива структур шаблонной функцией - C++
Как отсортировать с помощью шаблонной функции по значению полей в массиве структур? Кто знает, подскажите пожалуйста. Программа, которую...

Возвращение функцией значения динамического массива структур - C++
Auto readfile() { ifstream file(file); int i = 0, color; Auto *A = new Auto; while (!file.eof()) { file &gt;&gt; A.name &gt;&gt;...

Возврат функцией экземпляра класса - C++
Подскажите, будет ли корректной с точки зрения выделения памяти и всего прочего такая запись: MyObject fun(....) { myObject Obj =...

Возврат функцией указателя на функцию - C++
Всем привет! У меня возникла такая проблема: класс имеет поле-указатель на функцию. В методе, который осуществляет доступ к этуму полю,...

Возврат массива - C++
Не спрашивайте зачем я это делаю, если можно просто использовать strcpy. char tostrcpy(char *to, char *from); int main(int i) { ...

Возврат массива из функции - C++
Здравствуйте. Не могу разобраться, почему при передачи массива из функции но не правильно передаётся. Вот результат.

Возврат массива из функции - C++
Есть задача: используя функции, вычислить количество элементов заранее введённых массивов, которые кратны Х, и переписать в отдельный...

После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Kuzia domovenok
1890 / 1745 / 118
Регистрация: 25.03.2012
Сообщений: 5,924
Записей в блоге: 1
27.05.2014, 17:52     Возврат функцией массива структур #2
а зачем тебе узнавать размер поля? Он всегда постоянен!
Exzotick
0 / 0 / 0
Регистрация: 25.05.2014
Сообщений: 25
27.05.2014, 18:20  [ТС]     Возврат функцией массива структур #3
Например, чтобы задать ширину поля вывода для setw.
montkay
10 / 10 / 8
Регистрация: 19.02.2014
Сообщений: 72
27.05.2014, 18:57     Возврат функцией массива структур #4
Чтобы правильно передать массив структур нужно в сигнатуре функции указать следующие аргументы:
(students * pStud, int n) - если нам понадобиться изменять данные массива структур и этот массив создан динамически, или (const students * pStud, int n) - если нам не понадобиться изменять данные массива структур и этот массив создан динамически.

Чтобы узнать размер полей структуры можно ещё применить следующее:
1) name - sizeof(char) * name_size;
2) group - sizeof(char) * n;
3) age - sizeof(int);
4) average - sizeof(float);
5) scholarship - sizeof(float).
Kuzia domovenok
1890 / 1745 / 118
Регистрация: 25.03.2012
Сообщений: 5,924
Записей в блоге: 1
27.05.2014, 20:11     Возврат функцией массива структур #5
Цитата Сообщение от Exzotick Посмотреть сообщение
Например, чтобы задать ширину поля вывода для setw.
звучит бредово. При чём тут setw? Ты точно не путаешь с длиной строки? strlen(name) тебе ничего не говорит?
montkay
10 / 10 / 8
Регистрация: 19.02.2014
Сообщений: 72
27.05.2014, 20:56     Возврат функцией массива структур #6
Kuzia domovenok, если уж на то пошло, то нужно прописать как strlen(stud.name), где нужно сделать предварительное объявление и инициализацию student stud;
Exzotick
0 / 0 / 0
Регистрация: 25.05.2014
Сообщений: 25
28.05.2014, 08:58  [ТС]     Возврат функцией массива структур #7
Kuzia domovenok, вы мой код смотрели? Мне нужно вывести таблицу, и я хочу, чтобы под вывод имени отводилось столько знаков, сколько отведено под это поле в структуре.

Добавлено через 31 минуту
montkay, я правильно понимаю, что pStud - это указатель на массив структур, а n - количество его элементов? А нельзя создать массив и инициализировать его внутри функции, которая не принимает никаких параметров, возвращает только указатель на него, а потом присвоить значение этого указателя другому указателю в главной функции (как это я сделал)?

Добавлено через 13 минут
montkay, и еще по поводу размера поля. Конструкция "name - sizeof(char) * name_size;", насколько понимаю, возможна только потому, что я задал размер массива константой. А если он был задан просто числом (например, char name[30])?
montkay
10 / 10 / 8
Регистрация: 19.02.2014
Сообщений: 72
28.05.2014, 10:17     Возврат функцией массива структур #8
Сообщение было отмечено автором темы, экспертом или модератором как ответ
Exzotick, начну с последнего вашего вопроса. Чтобы узнать размер поля структуры нужно узнать размер типа данных это поля. Но если поле структуры представлено в виде массива, то нужно, помимо размера типа данных, указать также количество элементов массива. По этому чтобы узнать размер поля структуры char name[30] нужно sizeof(char) * 30.

Да, вы правильно поняли - pStud - это указатель на массив структур, а n - количество его элементов. Если создать массив структур внутри функции, то этот массив по завершению функции будет уничтожен (если этот массив будет создан на стеке, а если нет - то без очистки динамической памяти будет засорятся оперативка). И для того, чтобы сохранить массив в программе, нужно в функцию передавать значение по ссылке или по указателю. Количество элементов есть обязательным (если используется динамический массив, а это как раз ваш случай).

Передавать в главную функцию указатель как это сделали вы - недопустимо, потому что указатель должен указывать на существующий объект. Сейчас объясню. Вот вы создаете и инициализируете в функции массив, а по завершению функции он умирает. Тогда на что будет указывать возвращаемое значение? Фактически это может быть всё, что угодно, но вряд ли нужное вам значение. Чтобы функция возвращала указатель, нужно чтобы она принимала указатель, обрабатывала его каким-то образом, а потом возвращала его. Тогда проблем не будет, ведь возвращаемое значение - существует вне функции, которую вызываете вы, а следовательно - после завершения функции объект будет живым =) И не забывайте использовать количество элементов обязательно, чтобы всегда знать, какой кусок памяти нужно обработать. Ведь если не знать размера этого куска памяти, то программа вплоть до аварийного завершения будет его обрабатывать.
Exzotick
0 / 0 / 0
Регистрация: 25.05.2014
Сообщений: 25
28.05.2014, 13:20  [ТС]     Возврат функцией массива структур #9
Не могли бы вы все-таки описать функцию и как ее вызывать. А то у меня никак не получается это правильно сделать.
montkay
10 / 10 / 8
Регистрация: 19.02.2014
Сообщений: 72
28.05.2014, 15:34     Возврат функцией массива структур #10
Exzotick, хорошо. Только скажите какую именно функцию и что она должна делать.
Exzotick
0 / 0 / 0
Регистрация: 25.05.2014
Сообщений: 25
28.05.2014, 16:22  [ТС]     Возврат функцией массива структур #11
В функции main предоставляется выбор: заполнить массив вручную или использовать заготовку. Вот во втором случае массивом students_arr должен стать массив default_students_arr, который задан в функции use_arr.
montkay
10 / 10 / 8
Регистрация: 19.02.2014
Сообщений: 72
28.05.2014, 18:24     Возврат функцией массива структур #12
Приблизительно так может выглядеть функция. Но если вы захотите записать больше 8 человек в массив, то всем, кроме первых восьми, будет присвоено значение {"Nobody", "None", 0, 0.0, 0}.

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
void use_arr(students * pStud, int n)
{
    const int num_stud = 8;
    students stud_nobody = {"Nobody", "None", 0, 0.0, 0};
        students stud[num_stud] = {
        { "Урманов Роман Сергеевич", "Б8120", 18, 5.0, 7500 },
                { "Спицын Вячеслав Валерьевич", "Б8120", 17, 4.5, 0 },
                { "Аристова Дарья Павловна", "Б8120", 18, 4.0, 0 },
                { "Иванов Петр Владимирович", "М6180", 22, 5.0, 9000 },
                { "Дорошин Сергей Александрович", "М6180", 22, 4.9, 2800 },
                { "Годенко Николай Борисович", "Б5216", 19, 4.3, 2400 },
                { "Афанасьев Виктор Иванович", "Б5216", 19, 4.0, 1900 },
        { "Галинов Вячеслав Иванович", "Б5216", 19, 3.8, 0 }
    };
        for (int i = 0; i < n; i++)
        if (i < num_stud)
            pStud[i] = stud[i];
        else
            pStud[i] = stud_nobody;
}
Exzotick
0 / 0 / 0
Регистрация: 25.05.2014
Сообщений: 25
28.05.2014, 18:34  [ТС]     Возврат функцией массива структур #13
montkay, А почему эта функция не возвращает указатель? И еще, можно ли сделать так, чтобы первые восемь были записаны заранее, а остальные вводились с клавиатуры и добавлялись в массив?
montkay
10 / 10 / 8
Регистрация: 19.02.2014
Сообщений: 72
28.05.2014, 19:50     Возврат функцией массива структур #14
Эта функция не возвращает указатель, потому что суть её существования заключается в заполнении массива, который начинается по адресу "students * pStud", что указано в сигнатуре функции. Для чего нужно возвращать указатель? С помощью функции вы обрабатываете кусок памяти (для чего в сигнатуре нужно указывать начало массива и количество элементов). Если честно, то задам вам встречный вопрос, если вы не против - почему у вас многие функции возвращают значение? Не легче ли заполнить массив структур, а потом просто в нужный момент обращаться к членам массива и указывать их значение?

Да, можно вводить после восьмого студента вручную данные:

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
void use_arr(students * pStud, int n)
{
    const int num_stud = 8;
    students stud_nobody = {"Nobody", "None", 0, 0.0, 0};
    students stud[num_stud] = {
        { "Урманов Роман Сергеевич", "Б8120", 18, 5.0, 7500 },
        { "Спицын Вячеслав Валерьевич", "Б8120", 17, 4.5, 0 },
        { "Аристова Дарья Павловна", "Б8120", 18, 4.0, 0 },
        { "Иванов Петр Владимирович", "М6180", 22, 5.0, 9000 },
        { "Дорошин Сергей Александрович", "М6180", 22, 4.9, 2800 },
        { "Годенко Николай Борисович", "Б5216", 19, 4.3, 2400 },
        { "Афанасьев Виктор Иванович", "Б5216", 19, 4.0, 1900 },
        { "Галинов Вячеслав Иванович", "Б5216", 19, 3.8, 0 }
    };
    for (int i = 0; i < n; i++)
        if (i < num_stud)
            pStud[i] = stud[i];
        else
        {
            fill_name(pStud[i]);
            fill_group(pStud[i]);
            fill_age(pStud[i]);
            fill_average(pStud[i]);
            fill_scholaship(pStud[i]);
        }
}
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
28.05.2014, 19:51     Возврат функцией массива структур
Еще ссылки по теме:

Возврат массива из функции - C++
В объекте есть массив int state;, который мне нужно из него вытащить. Вижуал показывал ошибку, когда я пытался вернуть указатель state в...

Возврат массива из класса - C++
вот класс в котором есть массив а class Population1 { public: Population1(int,int); ~Population1(); int ProvLife(int,...

Возврат массива из функции - C++
Программа должна переводить числа с 10 системы в двоичную... но почемуто выводит некорректно... Вот код... #include &lt;iostream&gt; using...

Возврат массива из функции - C++
Здравствуйте, Не пойму почему не работает данный код. Пишет cannot convert 'std::string*' to 'int*' in return По теории я жду...

Возврат индексов двумерного массива - C++
Нужно получить индексы минимального элемента в матрице. Не понимаю, как передать индексы.Как-то через указатели? int min(int A,...


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

Или воспользуйтесь поиском по форуму:
Kuzia domovenok
1890 / 1745 / 118
Регистрация: 25.03.2012
Сообщений: 5,924
Записей в блоге: 1
28.05.2014, 19:51     Возврат функцией массива структур #15
Exzotick, а зачем его возвращать, если данные, переписанные по переданному в ф-ю указателю, сохранят свои изменения даже после выхода из функции?
Yandex
Объявления
28.05.2014, 19:51     Возврат функцией массива структур
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru