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

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

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

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

17.01.2013, 15:25. Просмотров 1434. Ответов 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;
}
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
17.01.2013, 15:25     Написать структуру типа STUDENT, создать динамический массив
Посмотрите здесь:

Создать структуру Student C++
Создать динамический массив, любого простого типа (например: int, long, float, double) C++
C++ Классы. Создать массив объектов. Student
C++ Отсортировать динамический массив указателей на структуру (по номеру группы)
Создать класс Matrix, реализующий двухмерный динамический массив типа int C++
C++ Создать структуру с именем STUDENT, содержащую следующие поля:
Создать динамический массив целого типа C++
C++ Создать класс student, который использует файл student.txt
Динамический массив указателей на структуру C++
Как создать и заполнить динамический массив строк типа std::string? C++
C++ Создать динамический массив объектов пользовательского типа
Создать структуру Student; в файл вывести студентов, сдавших сессию C++

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

Или воспользуйтесь поиском по форуму:
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
UserAK
71 / 71 / 4
Регистрация: 25.12.2012
Сообщений: 189
Записей в блоге: 2
17.01.2013, 15:42     Написать структуру типа STUDENT, создать динамический массив #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);
Asker
114 / 102 / 11
Регистрация: 18.12.2010
Сообщений: 378
17.01.2013, 16:36  [ТС]     Написать структуру типа STUDENT, создать динамический массив #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 минут
Вывод все равно не работает
Asker
114 / 102 / 11
Регистрация: 18.12.2010
Сообщений: 378
17.01.2013, 19:58  [ТС]     Написать структуру типа STUDENT, создать динамический массив #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;
}
Yandex
Объявления
17.01.2013, 19:58     Написать структуру типа STUDENT, создать динамический массив
Ответ Создать тему
Опции темы

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