Форум программистов, компьютерный форум, киберфорум
Наши страницы

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

Войти
Регистрация
Восстановить пароль
 
Рейтинг: Рейтинг темы: голосов - 10, средняя оценка - 4.80
Asker
116 / 104 / 11
Регистрация: 18.12.2010
Сообщений: 378
#1

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

17.01.2013, 15:25. Просмотров 1684. Ответов 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++):

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

Создать динамический массив объектов пользовательского типа - C++
Есть класс class address { } Нужно создать динамический массив объектов. Записи создаются по одной (адреса), их общее число не...

Создать структуру Student - C++
программа с использованием структуры полей структур. Успеваемость студентов. Фамилия студента, адрес,номер телефона, (Название месяца,...

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

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

Как создать и заполнить динамический массив строк типа std::string? - C++
Как создать и заполнить динамический массив строк типа string? Если заполнять массивы через getline(), почему то удаляется первая буква в...

3
UserAK
73 / 73 / 4
Регистрация: 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 / 11
Регистрация: 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 / 11
Регистрация: 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
17.01.2013, 19:58
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
17.01.2013, 19:58
Привет! Вот еще темы с ответами:

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

Как создать динамический массив типа string? Как создать класс такого массива? - C++
Как создать динамический массив типа string? Как создать класс такого массива? =-O Помогите, пожалуйста, очень нужна помощь!

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

Создать динамический массив, любого простого типа (например: int, long, float, double) - C++
1. Создать проект, который содержит консольную программу Win32. 2. Создать динамический массив, любого простого типа (например: int,...


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

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

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