Форум программистов, компьютерный форум, киберфорум
Наши страницы
С++ для начинающих
Войти
Регистрация
Восстановить пароль
 
Рейтинг: Рейтинг темы: голосов - 10, средняя оценка - 4.80
Asker
116 / 104 / 29
Регистрация: 18.12.2010
Сообщений: 378
#1

Написать структуру типа STUDENT, создать динамический массив - C++

17.01.2013, 15:25. Просмотров 1892. Ответов 3
Метки нет (Все метки)

Здравствуйте!

Мне нужно было написать структуру типа STUDENT, создать динамический массив размером n, прочитать с клавиатуры данные и записать их в поля структур...

Вводятся (для каждого STUDENT) следующие данные в отдельной строке: фамилия и имя, класс, дата рождения. Фамилия и имя – строки не более чем из 20 символов, класс – строка состоящая из числа (от 1 до 11) и латинской буквы (от "A" до "Z" ), дата рождения – дата в формате "ДД.ММ.ГГ" .

Программа сначала вводит, а потом опять выводит данные.

Она работает, но неправильно! В некоторых случаях, например, вводим:
Код
Ivanov
Ivan
11A
01.01.98
А выводит нечто вроде

Код
-32567= A Ivanov Ivan -842203136.-842203136.-842203136
Кто-нибудь знает, почему так??

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
// НАПИСАНО НА VISUAL 2008
#include <stdio.h>
#include <windows.h>
#include <string.h>
 
struct STUDENT
{
char Name[20], Surname[20]; 
char Letter;
short int Class;
int Day, Month, Year;
};
 
int main()
{
unsigned int n;
scanf("%i", &n);
STUDENT *a = new STUDENT [n]; // создали массив учащихся
 
for (unsigned int i=0; i<n; i++)
    scanf("%s%s%i%c%h.%h.%h", &a[i].Surname, &a[i].Name, &a[i].Class, 
       &a[i].Letter, &a[i].Day, &a[i].Month, &a[i].Year); 
 
for (unsigned  int i=0; i<n; i++)
     printf("%i%c %s %s %02i.%02i.%02i\n", a[i].Class, a[i].Letter, a[i].Surname, a[i].Name,
     a[i].Day, a[i].Month, a[i].Year); 
    
delete [] a;
 
system("pause");
 
return 0;
}
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
17.01.2013, 15:25
Я подобрал для вас темы с готовыми решениями и ответами на вопрос Написать структуру типа STUDENT, создать динамический массив (C++):

Создать динамический массив целого типа
Создать динамический массив целого типа на 100 элементов

Создать двумерный динамический массив типа String
Мне нужно создать динамический массив типа string с заранее неизвестной...

Создать динамический массив объектов пользовательского типа
Есть класс class address { } Нужно создать динамический массив...

Создать структуру Student
Не могу никак понять тему структуры, а тут сразу ещё и список, помогите...

Создать структуру Student
программа с использованием структуры полей структур. Успеваемость студентов. ...

Как создать и заполнить динамический массив строк типа std::string?
Как создать и заполнить динамический массив строк типа string? Если заполнять...

3
UserAK
73 / 73 / 13
Регистрация: 25.12.2012
Сообщений: 189
Записей в блоге: 2
17.01.2013, 15:42 #2
попробуйте для чисел использовать формат вывода %d

Добавлено через 5 минут
а ввода %i

Добавлено через 2 минуты
scanf("%s%s%i%c%i.%i.%i", &a[i].Surname, &a[i].Name, &a[i].Class,
&a[i].Letter, &a[i].Day, &a[i].Month, &a[i].Year);

Добавлено через 54 секунды
printf("%d%c %s %s %02d.%02d.%02d\n", a[i].Class, a[i].Letter, a[i].Surname, a[i].Name,
a[i].Day, a[i].Month, a[i].Year);
1
Asker
116 / 104 / 29
Регистрация: 18.12.2010
Сообщений: 378
17.01.2013, 16:36  [ТС] #3
Этот динамический массив надо потом отсортировать... сначала сортировать по классу, в классе по букве, в букве по фамилии, в фамилии по имени...

Почему не работает - понять я не могу...
ввод, как выяснилось благодаря UserAK, работает теперь исправно... Это значит, что ошибка где-то либо в swap, либо в операторе присваивания, либо в сортировке. Т.е. все так же выводит иногда билебирду...

код ниже. его не так много, как кажется, просто я прокомментировал немного
Кликните здесь для просмотра всего текста

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
// НАПИСАНО НА ВИЗЕ
/* */
#include <stdio.h>
#include <windows.h>
#include <string.h>
 
//using namespace std;
 
struct STUDENT // структура STUDENT
{
char Name[20], Surname[20]; // имя, фамилия
char Letter; // буква класса
short int Class; // Номер класса
int Day, Month, Year; // дата рождения
};
 
 
 
//--------------- перегрузка оператора > -------------
// Мы считаем a>b, если класс a больше, чем класс b
// если буква класса a больше, чем буква класса b
// если фамилия a в лексикографическом порядке дальше, чем 
// фамилия b (аналогично имя)
 
bool operator>(const STUDENT &a, const STUDENT &b)
{
bool res=false; 
int temp;
if (a.Class>b.Class) res=true;
 else if (a.Class==b.Class) 
    if (a.Letter>b.Letter) res=true;
    else if (a.Letter==b.Letter)
        {temp=strcmp(a.Surname, b.Surname);
        if (temp>0) res=true;
        else if (temp==0)
            if (strcmp(a.Name, b.Name)>0) res=true;
        }
return res;
};
 
//--- копирование структуры STUDENT b в структуру a
 
void copy(STUDENT &a, STUDENT &b)
{
a.Letter = b.Letter;
a.Class = b.Class;
a.Day=b.Day;
a.Month=b.Month;
a.Year=b.Year;
strcpy(a.Name, b.Name); // из-за строк пришлось ввести 
strcpy(a.Surname, b.Surname); // эту функцию
}
 
// --- функция обмена двух структур местами
 
void swap(STUDENT &a, STUDENT &b)
{
STUDENT temp;
copy(temp, a);
copy(a, b);
copy(b, temp);
}
 
// ------ MAIN ------------
 
int main()
{
unsigned int n;
scanf("%i", &n);
STUDENT *a = new STUDENT [n]; // создали массив учащихся
 
for (unsigned int i=0; i<n; i++) // это ввод, он работает
    scanf("%s%s%i%c%i.%i.%i", &a[i].Surname, &a[i].Name, &a[i].Class, 
       &a[i].Letter, &a[i].Day, &a[i].Month, &a[i].Year); 
 
for (unsigned int k=2; k<=n; k++) // сортировка пузырьком
    for (unsigned int i=0; i<=n-k; i++) // ошибка, наверно, где-нибудь здесь
        if (a[i]>a[i+1]) swap(a[i], a[i+1]); // если студент1>студент2, то
                                            // обменять местами
 
for (unsigned  int i=0; i<n; i++)  // это вывод, он работает
     printf("%d%c %s %s %02d.%02d.%02d\n", a[i].Class, a[i].Letter, a[i].Surname, a[i].Name,
     a[i].Day, a[i].Month, a[i].Year); 
    
delete [] a;
 
system("pause");
 
return 0;
}


Я был бы вам весьма признателен, если Вы поможете мне найти ошибку. Мне очень нужно понять этот материал...

Добавлено через 29 минут
Вывод все равно не работает
0
Asker
116 / 104 / 29
Регистрация: 18.12.2010
Сообщений: 378
17.01.2013, 19:58  [ТС] #4
УУУУУУУУУРАААААА!!! ВСЕ РАБОТАЕТ!

Я писал эту программу для электронной тестирующей системы (http://informatics.mccme.ru), которая довольно жестко относится к формату ввода/вывода. Поэтому тут есть примочки, которые рядового юзера не особо волнуют

Итак, задача звучала так:

Однажды, неловкая секретарша перепутала личные дела учащихся. Теперь их снова необходимо упорядочить сначала по классам, а внутри класса по фамилиям

Формат входного файла

В первой строке дано число N (1 ≤ N ≤ 1000) – количество личных дел. Далее для каждого из N учащихся следующие данные (каждое в своей строке): фамилия и имя, класс, дата рождения. Фамилия и имя – строки не более чем из 20 символов, класс – строка состоящая из числа (от 1 до 11) и латинской буквы (от "A" до "Z" ), дата рождения – дата в формате "ДД.ММ.ГГ" . Гарантируется, что внутри одного класса нет однофамильцев.


Формат выходного файла

В выходной файл требуется вывести N строк, в каждой из которых записаны данные по одному учащемуся. Строки должны быть упорядочены сначала по классам, а затем по фамилиям.


Я долго с ней мучался Ошибка заключалась в том, что scanf неверно распознавал ведущий нуль, и после этого в целочисленный тип дня/месяца/года записывал ASCII-номер символа точки. отсюда и билебирда Поэтому я переписал программу для iostream и реализовал чтение ведущего нуля...решил выложить сюда, может, кому пригодится

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
// НАПИСАНО НА visual c++ 2008
 
#include <iostream>
#include <windows.h>
#include <string>
 
using namespace std;
 
struct STUDENT // структура STUDENT
{
string Name, Surname; // имя, фамилия
char Letter;          // буква класса
short int Class;      // Номер класса
int Day, Month, Year; // дата рождения
};
 
/*Перегруженный оператор сравнения двух студентов.
Студент a считается большим студента b, если
полная лексикографическая запись a (номер класса,
буквы класса, фамилии и имени) стоит раньше, чем 
полная лекс. запись b*/
bool operator>(const STUDENT &a, const STUDENT &b)
{
bool res=false; 
if (a.Class>b.Class) res=true;
 else if (a.Class==b.Class) 
    if (a.Letter>b.Letter) res=true;
    else if (a.Letter==b.Letter)
        if (a.Surname>b.Surname) res=true;
        else if (a.Surname==b.Surname)
            if (a.Name>b.Name) res=true;
return res;
};
 
/*Функция обмена местами структур типа STUDENT*/
void swap(STUDENT &a, STUDENT &b)
{
STUDENT temp;
temp=a;
a=b;
b=temp;
}
 
/*Функция сканирует дату строго в формате DD.MM.YY,
(обязательно с ведущим нулём!), никакой защиты от 
ошибок и неправильного ввода не предусмотрено. Это 
можно потом доработать, и будет гуд*/
void scandate(int &day, int &month, int &year)
{
string temp;
std::cin >> temp;
day   = atoi(temp.substr(0,2).c_str());
month = atoi(temp.substr(3,2).c_str());
year  = atoi(temp.substr(6,2).c_str());
}
 
/*Функция выводит на экран число с ведущим нулём,
  если оно однозначное, в остальных случаях просто
  само число */
void z(int k)
{
if (k>9) cout << k;
else cout << "0" << k; 
}
 
// ------ MAIN ------------
 
int main()
{
unsigned int n;
cin >> n;
STUDENT *a = new STUDENT [n]; // создали массив из n учащихся
 
for (unsigned int i=0; i<n; i++) 
    {
    cin >> a[i].Surname >> a[i].Name >> a[i].Class >> a[i].Letter; // Вводим фамилию, имя, класс
    scandate(a[i].Day, a[i].Month, a[i].Year); // Дата рождения у нас - отдельный случай ;)
    }
 
for (unsigned int k=2; k<=n; k++) // сортировка пузырьком
    for (unsigned int i=0; i<=n-k; i++) 
        if (a[i]>a[i+1]) swap(a[i], a[i+1]); 
// сравниваем студентов и при необходимости меняем их местами
                                            
for (unsigned  int i=0; i<n; i++) 
// выводим в формате [класс][буква] [имя] [фамилия] [дата рожд.в формате DD.MM.YY]
    {cout << a[i].Class << a[i].Letter << " " << a[i].Surname << " " << a[i].Name << " ";
    z(a[i].Day);
    cout << "."; 
    z(a[i].Month); 
    cout << ".";
    z(a[i].Year);
    cout << endl;}
    
delete [] a; // освобождаем память
 
system("pause");
 
return 0;
}
1
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
17.01.2013, 19:58
Привет! Вот еще темы с решениями:

Создать класс Matrix, реализующий двухмерный динамический массив типа int
Здравствуйте! Задание: Создать класс Matrix, реализующий двухмерный ...

Создать структуру с именем Student с полями
Не знаю даже примерно как нужно сделать, не шарю. Отчет надо сдать (( ...

Как создать динамический массив типа string? Как создать класс такого массива?
Как создать динамический массив типа string? Как создать класс такого массива? ...

Посмотрите объявление вектора и попытайтесь создать динамический массив, содержащий элементы типа char
#include &lt;iostream&gt; #include &lt;vector&gt; using namespace std; int main() {...


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

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

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