0 / 0 / 0
Регистрация: 26.02.2012
Сообщений: 9
1

Вывести на экран фамилии и имена трех худших по среднему баллу учеников

26.02.2012, 22:00. Показов 2201. Ответов 17
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
задача
На вход программе подаются сведения о сдаче экзаменов учениками 9-х классов некоторой средней школы. В первой строке сообщается количество учеников N, которое не меньше 10, но не превосходит 100, каждая из следующих N строк имеет следующий формат:
<Фамилия> <Имя> <оценки>,
где <Фамилия> – строка, состоящая не более чем из 20 символов, <Имя> – строка, состоящая не более чем из 15 символов, <оценки> – через пробел три целых числа, соответствующие оценкам по пятибалльной системе. <Фамилия> и <Имя>, а также <Имя> и <оценки> разделены одним пробелом. Пример входной строки:
Иванов Петр 4 5 3
Требуется написать как можно более эффективную программу (укажите используемую версию языка программирования, например, Borland Pascal 7.0), которая будет выводить на экран фамилии и имена трех худших по среднему баллу учеников. Если среди остальных есть ученики, набравшие тот же средний балл, что и один из трех худших, то следует вывести и их фамилии и имена.


А вот мое "решение":
Код:

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 <iostream>
#include <string.h>
#include <math.h>
 
struct data
{
     int sum;
     char *user;
};
 
void packer (char *tmpD, data *pupin, int i)
{
    pupin[i].user = new char[37];
    pupin[i].user = strtok(tmpD," ");
    strcat(pupin[i].user, " ");
    strcat(pupin[i].user, strtok(NULL," "));
 
    pupin[i].sum=atoi(strtok(NULL," "))+atoi(strtok(NULL," "))+atoi(strtok(NULL," "));
 
}
 
int main()
{
    int N=4;
    int const S=43;
    data *pupin = new data [N];
    char *tmpData = new char[S] ;
 
    for (int i=0; i<N; i++)
    {
        std::cout<<"Введите данные участника:"<<std::endl;
        std::cin.getline(tmpData,S);
        packer ( tmpData, pupin, i);
    }
 
    data min1, min2, min3;
    min1.sum=min2.sum=min3.sum=15;
 
 
    for(int i=0; i<N; i++)
    {
        if(pupin[i].sum<=min1.sum)
        {
            data tmp=min1;
            min1=pupin[i];
            min3=min2;
            min2=tmp;
        }
        else if (pupin[i].sum<=min2.sum)
        {
            min3=min2;
            min2=pupin[i];
        }
        else if(pupin[i].sum <= min3.sum)
            min3=pupin[i];
    }
 
    std::cout<<"Ученики с наименьшими результатом:"<<std::endl
        <<min1.user<<std::endl
        <<min2.user<<std::endl
        <<min3.user<<std::endl;
    
    for(int i=0; i<N; i++)
        if(pupin[i].sum==min3.sum)
            std::cout<<pupin[i].user<<std::endl;
 
    int r;
    std::cin>>r;
        
}
Не могу разобраться, почему во время выполнения программы все время вылазят ошибки "доступа" и ghjxtt.. разъясните,пожалуйста,что здесь не так..п.с.компилировал на Visual Studio 2010
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
26.02.2012, 22:00
Ответы с готовыми решениями:

Вывести фамилии и имена трех худших по среднему баллу учеников
На вход программе подаются сведения о сдаче экзаменов учениками 9-х классов некоторой средней...

Вывести фамилии и имена трех худших по среднему баллу учеников
На вход программе подаются сведения о сдаче экзаменов учениками 9-х классов некоторой средней...

Вывести имена трех худших по баллу
Вот условие На вход программе подаются сведения о сдаче экзаменов учениками 11-х классов некоторой...

Вывести на экран фамилии и имена трех худших по среднему баллу учеников
На вход программе подаются сведения о сдаче экзаменов учениками 9-х классов некоторой средней...

17
594 / 532 / 76
Регистрация: 22.03.2011
Сообщений: 1,585
27.02.2012, 02:17 2
для начала так:
C
1
2
3
4
5
6
7
8
9
10
void packer (char *tmpD, data *pupin, int i)
{
pupin[i].user = new char[37];
strcpy(pupin[i].user,strtok(tmpD," "));
strcat(pupin[i].user, " ");
strcat(pupin[i].user, strtok(NULL," "));
 
pupin[i].sum=atoi(strtok(NULL," "))+atoi(strtok(NULL," "))+atoi(strtok(NULL,"\n"));
 
}
1
0 / 0 / 0
Регистрация: 26.02.2012
Сообщений: 9
27.02.2012, 11:19  [ТС] 3
Спасибо! проглядел этот момент)
Подскажите еще, что в нижеприведенном коде не так?

C++
1
2
3
4
5
6
7
8
9
10
11
#include "stdafx.h"
 
 
int main()
{
    int N;
    std::cin>>N;
    int i=0;
    while(i<=N)
        i++;
}
суть в том, что количество интераций циклов пользователь должен ввести с клавиатуры....но вылазит ошибка доступа...как этого можно избежать??

Добавлено через 1 час 6 минут
вот например, если после строки исходного когда: char *tmpData = new char[S] ;

вставить : std::cin>>N;

вылазит ошибка(
0
Полярный
476 / 448 / 158
Регистрация: 11.09.2011
Сообщений: 1,156
27.02.2012, 11:32 4
Нет ошибки:
http://liveworkspace.org/code/... f9cf10eafb
И зачем вам stdafx.h?

Добавлено через 1 минуту
Цитата Сообщение от cooky Посмотреть сообщение
интераций
итераций
0
0 / 0 / 0
Регистрация: 26.02.2012
Сообщений: 9
27.02.2012, 11:45  [ТС] 5
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
#include <iostream>
#include <string.h>
#include <math.h>
 
 
 
 
 
struct data
{
    int sum;
    char *user;
};
 
void packer (char *tmpD, data *pupin, int i)
{
   pupin[i].user = new char[37];
   strcpy(pupin[i].user, strtok(tmpD," "));
   strcat(pupin[i].user, " ");
   strcat(pupin[i].user, strtok(NULL," "));
 
   pupin[i].sum=atoi(strtok(NULL," "))+atoi(strtok(NULL," "))+atoi(strtok(NULL,"\n"));
 
}
 
int main()
{
   int N=5;
   int const S=43;
   data *pupin = new data [N];
   char *tmpData = new char[S] ;
   
   
   
 
   for (int i=0; i<N; i++)
   {
      std::cout<<"Введите данные участника:"<<std::endl;
      std::cin.getline(tmpData,S);
      packer ( tmpData, pupin, i);
   }
 
   data min1, min2, min3;
   min1.sum=min2.sum=min3.sum=15;
 
 
   for(int i=0; i<N; i++)
   {
      if(pupin[i].sum<=min1.sum)
      {
         data tmp=min1;
         min1=pupin[i];
         min3=min2;
         min2=tmp;
      }
      else if (pupin[i].sum<=min2.sum)
      {
         min3=min2;
         min2=pupin[i];
      }
      else if(pupin[i].sum <= min3.sum)
         min3=pupin[i];
   }
 
   std::cout<<"Ученики с наименьшими результатом:"<<std::endl
      <<min1.user<<std::endl
      <<min2.user<<std::endl
      <<min3.user<<std::endl;
   
   
 
   return 0;
      
}
Тут все работает идеально
Но если я добавляю 2 сточки:
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
#include <iostream>
#include <string.h>
#include <math.h>
 
 
 
 
 
struct data
{
    int sum;
    char *user;
};
 
void packer (char *tmpD, data *pupin, int i)
{
   pupin[i].user = new char[37];
   strcpy(pupin[i].user, strtok(tmpD," "));
   strcat(pupin[i].user, " ");
   strcat(pupin[i].user, strtok(NULL," "));
 
   pupin[i].sum=atoi(strtok(NULL," "))+atoi(strtok(NULL," "))+atoi(strtok(NULL,"\n"));
 
}
 
int main()
{
   int N=5;
   int const S=43;
   data *pupin = new data [N];
   char *tmpData = new char[S] ;
   
   
   std::cout<<"Введите чило участников:";                            \\вот они!!!!!!!!!!!!!!!!!
   std::cin>>N;
 
   for (int i=0; i<N; i++)
   {
      std::cout<<"Введите данные участника:"<<std::endl;
      std::cin.getline(tmpData,S);
      packer ( tmpData, pupin, i);
   }
 
   data min1, min2, min3;
   min1.sum=min2.sum=min3.sum=15;
 
 
   for(int i=0; i<N; i++)
   {
      if(pupin[i].sum<=min1.sum)
      {
         data tmp=min1;
         min1=pupin[i];
         min3=min2;
         min2=tmp;
      }
      else if (pupin[i].sum<=min2.sum)
      {
         min3=min2;
         min2=pupin[i];
      }
      else if(pupin[i].sum <= min3.sum)
         min3=pupin[i];
   }
 
   std::cout<<"Ученики с наименьшими результатом:"<<std::endl
      <<min1.user<<std::endl
      <<min2.user<<std::endl
      <<min3.user<<std::endl;
   
   
 
   return 0;
      
}

вылазят ошибки(

Добавлено через 4 минуты
во всяком случае, на моем компиляторе так..

Добавлено через 2 минуты
после ввода "числа участников" вылазит
"Необработанное исключение в "0x1027d2f3 (msvcr100d.dll)" в "EVILcooky.exe": 0xC0000005: Нарушение прав доступа при чтении "0x00000000"."
0
62 / 62 / 11
Регистрация: 16.10.2011
Сообщений: 200
27.02.2012, 13:57 6
Код вообще бередовый. У тебя есть массив с данными, под который ты выделяешь память. У тебя сначало N = 5, затем ты выделяешь память под 5! элементов, а затем вводишь N. Т.е. ты выделил память под 5! элементов, затем ввел N = 100, начал перебор всех, и когда у тебя i становится >= 5, то понятное дело вылезет исключение, ведь массив у тебя всего на 5 элементов.
Тебе надо сначало запрашивать ввод N, а уже после этого выделять память под массив.
0
0 / 0 / 0
Регистрация: 26.02.2012
Сообщений: 9
27.02.2012, 14:09  [ТС] 7
C++
1
2
3
4
5
6
7
int N;
    int const S=43;
    std::cout<<"Введите чило участников:";
    std::cin>>N;
    
    data *pupin = new data [N];
    char *tmpData = new char[S] ;
подправил эту часть кода и все равно во время ввода N вылазит та же ошибка

Добавлено через 3 минуты
а если я нициализирую N(любым значением) в самой программе, то все идет отлично...
0
62 / 62 / 11
Регистрация: 16.10.2011
Сообщений: 200
27.02.2012, 14:22 8
Скинь заново весь подправленный код.

Добавлено через 5 минут
Одна из твоих ошибок - ты неправильно используешь функцию strtok

Добавлено через 4 минуты
strcpy(pupin[i].user, strtok(tmpD," "));
Что тут получается? В строке tmpD ищется символ пробела, возращается на него указатель. А далее ты копируешь все, что стоит после пробела. А нужно наоборот копировать все что стоит до пробела.
strtok(NULL," ") - Такая запись вообще не имее смысла, т.к. на месте NULL должна стоять строка, в которой выполняется поиск. А вообще советую читать MSDN!

Добавлено через 45 секунд
Я бы посоветовал сделать через потоки, либо используя функцию sscanf
1
0 / 0 / 0
Регистрация: 26.02.2012
Сообщений: 9
27.02.2012, 14:41  [ТС] 9
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
#include <iostream>
#include <string.h>
#include <math.h>
 
 
 
 
 
struct data
{
    int sum;
    char *user;
};
 
void packer (char*, data*, int );
 
int main()
{
   int N;
   std::cout<<"Введите число участников: ";
   std::cin>>N;
   //Если убрать эти строки и инициализировать N прямо в коде - ошибок не будет.почему?
   
 
   int const S=43;
   
   
   
   data *pupin = new data [N];
   char *tmpData = new char[S] ;
   
   
   
 
   for (int i=0; i<N; i++)
   {
      std::cout<<"Введите данные участника:"<<std::endl;
      std::cin.getline(tmpData,S);
      packer ( tmpData, pupin, i);
   }
 
   data min1, min2, min3;
   min1.sum=min2.sum=min3.sum=15;
 
 
   for(int i=0; i<N; i++)
   {
      if(pupin[i].sum<=min1.sum)
      {
         data tmp=min1;
         min1=pupin[i];
         min3=min2;
         min2=tmp;
      }
      else if (pupin[i].sum<=min2.sum)
      {
         min3=min2;
         min2=pupin[i];
      }
      else if(pupin[i].sum <= min3.sum)
         min3=pupin[i];
   }
 
   std::cout<<"Ученики с наименьшими результатом:"<<std::endl
      <<min1.user<<std::endl
      <<min2.user<<std::endl
      <<min3.user<<std::endl;
   
   
 
   return 0;
      
}
 
 
 
 
 
void packer (char *tmpD, data *pupin, int i)
{
   pupin[i].user = new char[37];
   strcpy(pupin[i].user, strtok(tmpD," "));
   strcat(pupin[i].user, " ");
   strcat(pupin[i].user, strtok(NULL," "));
 
   pupin[i].sum=atoi(strtok(NULL," "))+atoi(strtok(NULL," "))+atoi(strtok(NULL,"\n"));
 
}
 Комментарий модератора 
выкладывай код на форум!

Вот "исправленный вариант"..
а можете привести в качестве примера фрагмен кода с ипользованием "потоков" или ф-ции сканф
только условие следующее: данные о участнике(фамилия имя оценка оценка оценка) вводятся в одну строку, как указано в задании выше

Добавлено через 11 минут
Что тут получается? В строке tmpD ищется символ пробела, возращается на него указатель. А далее ты копируешь все, что стоит после пробела. А нужно наоборот копировать все что стоит до пробела.
Он возвращает указатель на первую лексему, то есть, внашем случае, Фамилию участника..место пробела заменятеся символом конца строки....помоему так)) ну в этой части программа работает правильно
0
62 / 62 / 11
Регистрация: 16.10.2011
Сообщений: 200
28.02.2012, 08:36 10
Приведи пример строки ввода.

Добавлено через 8 минут
С использование sscanf получится вот так:
C++
1
2
3
4
5
6
7
void packer (char *tmpD, data *pupin, int i)
{
   pupin[i].user = new char[37];
   int a1, a2, a3;
   sscanf(tmpD, "%*s %36s %i %i %i", pupin[i].user, &a1, &a2, &a3);
   pupin[i].sum = a1 +a2 + a3;
}
Лучше будет использовать sscanf_s - это безопасная версия sscanf. Там просто на один аргумент будет больше и это длина строки tmpD.
Ну и можешь попробовать через std::cin считать. Это тоже не сложно, писать пока не буду.
1
0 / 0 / 0
Регистрация: 26.02.2012
Сообщений: 9
28.02.2012, 08:37  [ТС] 11
Ремизова Валерия 5 4 3
0
62 / 62 / 11
Регистрация: 16.10.2011
Сообщений: 200
28.02.2012, 08:45 12
В моем примере, в строку имени занесется Валерия.
Вызов strtok(NULL," ") вызовет исключение(или просто вернет NULL) Эта функция ищет в строке первую встречу символов из другой строки. А то что ты написал, ты вместо строки передаешь NULL и ищешь пробел...
В строке tmpD = "Ремизова Валерия 5 4 3" вызов char *a = strtok(tmpD, " ") Вернет указатель на пробел. Т.е. строка 'a' буде равна " Валерия 5 4 3" вызов a = strtok(a + 1, " ") Вернет указатель на второй пробел т.е. " 5 4 3".
Пока все, потом смогу отписаться только вечером.
0
Эксперт С++
5828 / 3479 / 358
Регистрация: 08.02.2010
Сообщений: 7,448
28.02.2012, 09:11 13
Цитата Сообщение от darkknight2008 Посмотреть сообщение
strtok(NULL," ") - Такая запись вообще не имее смысла, т.к. на месте NULL должна стоять строка, в которой выполняется поиск. А вообще советую читать MSDN!
это не так. Советую почитать маны

Добавлено через 1 минуту
Цитата Сообщение от darkknight2008 Посмотреть сообщение
Вызов strtok(NULL," ") вызовет исключение(или просто вернет NULL)
нет, не вызовет, это вообще С-ая функция. И NULL она вернет только при определеном случае
0
0 / 0 / 0
Регистрация: 26.02.2012
Сообщений: 9
28.02.2012, 09:19  [ТС] 14
Цитата Сообщение от Nameless One Посмотреть сообщение
это не так. Советую почитать маны

Добавлено через 1 минуту

нет, не вызовет, это вообще С-ая функция. И NULL она вернет только при определеном случае
strtok(stroka, " "); -вернет первую лексему строки

strtok(NULL, " "); -вторая лексема строки

и работает моя программа именно так...выше есть рабочий вариант, проверь..
0
Эксперт С++
5828 / 3479 / 358
Регистрация: 08.02.2010
Сообщений: 7,448
28.02.2012, 09:21 15
cooky, так я тебе ничего и не говорил. Я отвечал на необоснованные утверждения darkknight2008
0
0 / 0 / 0
Регистрация: 26.02.2012
Сообщений: 9
28.02.2012, 09:33  [ТС] 16
Nameless One, извиняюсь)
C++
1
2
3
4
5
6
7
8
9
10
void packer (char *tmpD, data *pupin, int i)
{
   pupin[i].user = new char[37];
   strcpy(pupin[i].user, strtok(tmpD," "));
   strcat(pupin[i].user, " ");
   strcat(pupin[i].user, strtok(NULL," "));
 
   pupin[i].sum=atoi(strtok(NULL," "))+atoi(strtok(NULL," "))+atoi(strtok(NULL,"\n"));
 
}
вообщем, мой вариант,конечно,чудовещный, но работает он чОтка
0
62 / 62 / 11
Регистрация: 16.10.2011
Сообщений: 200
28.02.2012, 15:16 17
Да, простите облажался(( После вызова std::cin >> N; в потоке ввода остается символ перевода строки. Поэтому при вызове std::cin.getline(tmpData,S); сразу ловится символ перевода строки и считается, что ввод закончен, т.е. строка остается пустой. Чтобы его отловить, можно после std::cin >> N; вставить getchar() либо std::cin.ignore();
1
0 / 0 / 0
Регистрация: 26.02.2012
Сообщений: 9
28.02.2012, 15:29  [ТС] 18
Вот оно!))спасибо огромное)
0
28.02.2012, 15:29
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
28.02.2012, 15:29
Помогаю со студенческими работами здесь

Вывести на экран фамилии и имена трех худших по среднему баллу учеников
Помогите с информатикой?QBASIK На вход программе подаются сведения о сдаче экзаменов учениками...

Вывести на экран фамилии и имена трех худших по среднему баллу учеников
uses crt; const LIM = 100; var Info: array of record name: string; sum: integer; end; i, k,...

Вывести на экран фамилии и имена трех лучших по среднему баллу учеников
На вход программе подаются сведения о сдаче экзаменов учениками 9-х классов некоторой средней...

Вывести на экран фамилии и имена трех лучших по среднему баллу учеников
задача 1 Во входном файле meteo.dat 365 строк, которые содержат информацию о среднесуточной...


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

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

Новые блоги и статьи
Как подключить JavaScript файл в другом JavaScript файле
InfoMaster 20.01.2025
В современной веб-разработке организация кодовой базы играет ключевую роль в создании масштабируемых и поддерживаемых приложений. Модульность и правильное структурирование кода стали неотъемлемыми. . .
Как откатить изменения в исходниках, не внесенные в Git
InfoMaster 20.01.2025
При работе с системой контроля версий Git разработчики часто сталкиваются с необходимостью отменить внесенные изменения в исходном коде. Особенно актуальной становится ситуация, когда изменения еще. . .
В чем разница между px, in, mm, pt, dip, dp, sp
InfoMaster 20.01.2025
В мире цифрового дизайна и разработки интерфейсов правильный выбор единиц измерения играет ключевую роль в создании качественного пользовательского опыта. История развития систем измерений для. . .
Как изменить адрес удалённого репозитория (origin) в Git
InfoMaster 20.01.2025
В терминологии Git термин origin является стандартным именем для основного удаленного репозитория, с которым взаимодействует локальная копия проекта. Когда разработчик клонирует репозиторий с. . .
Как переместить последние коммиты в новую ветку (branch) в Git
InfoMaster 20.01.2025
При работе над проектом часто возникают ситуации, когда необходимо изолировать определенные изменения от основной линии разработки. Это может быть связано с экспериментальными функциями, исправлением. . .
Как вернуть результат из асинхронной функции в JavaScript
InfoMaster 20.01.2025
Асинхронное программирование представляет собой фундаментальную концепцию в JavaScript, которая позволяет выполнять длительные операции без блокировки основного потока выполнения программы. В. . .
Какой локальный веб-сервер выбрать
InfoMaster 19.01.2025
В современной веб-разработке локальные веб-серверы играют ключевую роль, предоставляя разработчикам надежную среду для создания, тестирования и отладки веб-приложений без необходимости использования. . .
Почему планшеты и iPad уже не так популярны, как раньше
InfoMaster 19.01.2025
Эра революционных инноваций История планшетных компьютеров началась задолго до того, как эти устройства стали привычными спутниками нашей повседневной жизни. В начале 1990-х годов появились первые. . .
Как самому прошить BIOS ноутбука
InfoMaster 19.01.2025
BIOS (Basic Input/ Output System) представляет собой важнейший компонент любого компьютера или ноутбука, который обеспечивает базовое взаимодействие между аппаратным и программным обеспечением. . .
Какой Linux выбрать для домашнего компьютера
InfoMaster 19.01.2025
Современные реалии выбора операционной системы В современном мире выбор операционной системы для домашнего компьютера становится все более важным решением, которое может существенно повлиять на. . .
Как объединить два словаря одним выражением в Python
InfoMaster 19.01.2025
В мире программирования на Python работа со словарями является неотъемлемой частью разработки. Словари представляют собой мощный инструмент для хранения и обработки данных в формате "ключ-значение". . . .
Как без исключения проверить существование файла в Python
InfoMaster 19.01.2025
При разработке программного обеспечения на Python часто возникает необходимость проверить существование файла перед выполнением операций с ним. Это критически важная задача, которая помогает избежать. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru