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

Сортировка массив структур: qsort выдает Expression syntax

13.06.2012, 01:27. Показов 2043. Ответов 23
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Имеется код для сортировки массива структур:
C
1
qsort (base, n, sizeof(people), namecmp);
C
1
2
3
4
int namecmp (const void * a, const void * b)
{
    return strcmp (((people*)a).FIO, ((people*)b).FIO);
}
При вызове функции namecmp пишет: E2188 Expression syntax. Не могу понять, в чем ошибка?
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
13.06.2012, 01:27
Ответы с готовыми решениями:

Сортировка массива структур с использованием qsort
Народ прошу помощи, нужно отсортировать массив структур с помощью функции qsort() typedef...

Сортировка массива структур без использования Qsort
Здравствуйте! Для сортировки массива структур я использовал стандартную функцию qsort(), но как...

Error E2188 expression syntax
Error E2188 expression syntax Из-за чего может быть? Кавычками отметила место на которое...

Expression syntax как исправить?
//--------------------------------------------------------------------------- #include <stdio.h>...

23
Модератор
Эксперт PythonЭксперт JavaЭксперт CЭксперт С++
12438 / 7465 / 1749
Регистрация: 25.07.2009
Сообщений: 13,721
13.06.2012, 01:57 2
Цитата Сообщение от razer89 Посмотреть сообщение
return strcmp (((people*)a).FIO, ((people*)b).FIO);
C
1
return strcmp( ((people*)a)->FIO, ((people*)b)->FIO );
так отработает?
0
15 / 15 / 0
Регистрация: 20.06.2010
Сообщений: 142
13.06.2012, 02:44  [ТС] 3
Цитата Сообщение от easybudda Посмотреть сообщение
Код C
1 return strcmp( ((people*)a)->FIO, ((people*)b)->FIO );
так отработает?
Неа...
ЗЫ: Компилятор - Embarcadero RAD Studio
0
Модератор
Эксперт PythonЭксперт JavaЭксперт CЭксперт С++
12438 / 7465 / 1749
Регистрация: 25.07.2009
Сообщений: 13,721
13.06.2012, 03:36 4
Лучший ответ Сообщение было отмечено Памирыч как решение

Решение

Цитата Сообщение от razer89 Посмотреть сообщение
Неа...
Тогда больше кода нужно. Как структура объявлена? Как массив заполняется?
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
#include <stdio.h>
#include <stdlib.h>
 
typedef struct {
    char * name;
    int growth;
} person_t;
 
int name_cmp(const void * a, const void * b) {
    return strcmp(((person_t*)a)->name, ((person_t*)b)->name);
}
 
#define PERSONS 3
 
int main(void) {
    person_t array[PERSONS] = {
        { "Petrov", 178 },
        { "Sidorov", 175 },
        { "Ivanov", 180 }
    };
    int i;
    
    printf("Unsorted:\n");
    for ( i = 0; i < PERSONS; ++i )
        printf("%s\t%d\n", array[i].name, array[i].growth);
    qsort(array, PERSONS, sizeof(person_t), name_cmp);
    printf("Sorted by name:\n");
    for ( i = 0; i < PERSONS; ++i )
        printf("%s\t%d\n", array[i].name, array[i].growth);
    
    return 0;
}
http://codepad.org/1gZZm5LV
0
15 / 15 / 0
Регистрация: 20.06.2010
Сообщений: 142
13.06.2012, 09:44  [ТС] 5
Цитата Сообщение от easybudda Посмотреть сообщение
Тогда больше кода нужно. Как структура объявлена? Как массив заполняется?
Вот весь код:
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
135
136
137
138
139
140
141
142
143
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
 
//---------------------------------------------------------------------------
FILE *database;
struct {char FIO [25]; float s2; int amount;} people;
 
void view_all();
void add_item();
void sort();
int namecmp(const void* a, const void* b);
int s2cmp(const void* a, const void* b);
int amount(const void* a, const void* b);
 
void main()
{
    int t;
 
    if ((database = fopen ("database.db", "rb+")) == NULL)
    {
        printf ("File not found! Create new? [Y/N] \n");
        char n [1];
        scanf ("%s", n);
        if (n[0] == 'y')
        {
            database = fopen ("database.db", "wb+");
            system ("cls");
        }
        else
        {
            t = 10;
        }
    }
    fclose (database);
 
    if (t != 10)
    {
 
        do
        {
            printf ("[1]View All\t[2]Add Item\t[0]Exit\n");
            scanf ("%d", &t);
            switch (t) {
                case 1: system("cls");
                    view_all();
                    break;
 
                case 2: system("cls");
                    add_item();
                    break;
                case 3: system("cls");
                    sort();
                    break;
            }
        }
        while (t != 0);
    }
}
 
void view_all()
{
    database = fopen ("database.db", "rb");
    fread (&people, sizeof (people), 1, database);
    while (!feof(database))
    {
        printf ("FIO \t\tSquare \t\tAmount \n%s \t\t%f \t%i \n", people.FIO, people.s2, people.amount);
        fread (&people, sizeof (people), 1, database);
    }
    fclose (database);
    system ("pause"); system ("cls");
}
 
void add_item()
{
    database = fopen ("database.db", "ab");
    puts ("Input FIO");
    scanf ("%s", &people.FIO);
    puts ("Input square");
    scanf ("%f", &people.s2);
    puts ("Input amount");
    scanf ("%i", &people.amount);
    system ("cls");
    fwrite (&people, sizeof(people), 1, database);
    fclose (database);
}
 
void sort()
{
    int i = 0;
    int c;
    struct {char FIO [25]; float s2; int amount;} base [100];
    database = fopen ("database.db", "rb");
 
    while (!feof(database))
    {
        fread (&people, sizeof (people), 1, database);
        strcpy (base[i].FIO, people.FIO);
        base[i].s2 = people.s2;
        base[i].amount = people.amount;
    }
 
    printf ("Sort by: \n[1]FIO \t[2]Square \t[3]Amount");
    scanf ("%d", &c);
    int n = i;
    switch (c)
    {
        case 1: system("cls");
        qsort (base, n, sizeof(people), namecmp);
        for (i = 0; i < n; i++)
        {
            printf ("%s\t%f\t%i", base.FIO, base.s2, base.amount);
        }
        break;
 
 
        case 2: system("cls");
        break;
 
        case 3: system("cls");
        break;
 
    }
}
 
int namecmp (const void * a, const void * b)
{
    return strcmp ( ((people*)a)->FIO, ((people*)b)->FIO);
}
 
int s2cmp (const void* a, const void* b)
{
    float d = ((people*)a).s2 - ((people*)b)s2;
    return ( d < 0.0 ) ? -1 : ( d > 0.0 ) ? 1 : 0;
}
 
int amountcmp (const void* a, const void* b)
{
    return (*(people*)a).amount - (*(people*)b).amount;
}
 
 
//---------------------------------------------------------------------------
0
Модератор
Эксперт PythonЭксперт JavaЭксперт CЭксперт С++
12438 / 7465 / 1749
Регистрация: 25.07.2009
Сообщений: 13,721
13.06.2012, 12:24 6
razer89, ошибок в коде, как у дурака махорки...
1. Что в программе на С делает #include <iostream>? Оно, конечно, ничего, если компилировать, как С++ код, но именно как С ни за какие коврижки не скомпилируется.
2. Перед объявлением структуры typedef поставьте. В таком виде объявляется безымянная структура и единственная переменная этой структуры.
3. Внешние переменные без серьёзной на то необходимости - это плохо не только по религиозным соображениям. Попробуйте отследить, сколько раз в коде файл с базой пытается открыться, при чём в разных режимах, практически без проверок, а где он при этом хоть раз закрывается - не увидел.
4. (И тут до меня дошло, что people таки внешняя переменная) при считывании из файла в массив во-первых смело создавать массив из 100 элементов не заморачиваясь, больше их в файле, меньше, а то и вовсе нет ни одного, а во вторых переменная i так всё время нулём и остаётся, то есть если бы что и считывалось - попадало бы в первый элемент массива, затирая то, что там было.
Функцию сравнения по именам изменили, а остальные? Они тоже не правильные.
5. Куча опечаток, заметных, если присмотреться.
Ну и функция main() всё-таки должна иметь тип int и по своему завершению возвращать целое число - код завершения (0 - успешно, не 0 - что-то пошло не так...)
1
15 / 15 / 0
Регистрация: 20.06.2010
Сообщений: 142
13.06.2012, 22:32  [ТС] 7
Цитата Сообщение от easybudda Посмотреть сообщение
ошибок в коде, как у дурака махорки...
Я студент первого курса, я только учусь... =)
Цитата Сообщение от easybudda Посмотреть сообщение
Что в программе на С делает #include <iostream>?
Без него ругается на строку
Цитата Сообщение от razer89 Посмотреть сообщение
strcpy (base[i].FIO, people.FIO);
E2268 Call to undefined function 'strcpy'
Цитата Сообщение от easybudda Посмотреть сообщение
Внешние переменные без серьёзной на то необходимости - это плохо не только по религиозным соображениям.
Посоветуйте, как поступить в конкретном случае, чтобы избавиться от внешней переменной?
Цитата Сообщение от easybudda Посмотреть сообщение
практически без проверок
Проверка проволится только при первом запуске программы. В остальных случаях не считаю ее целесообразной (поправте, если не прав).
Цитата Сообщение от easybudda Посмотреть сообщение
а где он при этом хоть раз закрывается - не увидел
Цитата Сообщение от razer89 Посмотреть сообщение
fclose (database);
Цитата Сообщение от easybudda Посмотреть сообщение
смело создавать массив из 100 элементов не заморачиваясь
Подскажите, как создать массив с нужным количеством элементов?
Цитата Сообщение от easybudda Посмотреть сообщение
а во вторых переменная i так всё время нулём и остаётся
Это не окончательный код, я планирую ее использовать... =)
Цитата Сообщение от easybudda Посмотреть сообщение
Функцию сравнения по именам изменили, а остальные? Они тоже не правильные.
Компилятор ругается и на исправленную, и на неиспраленную функцию...
Цитата Сообщение от easybudda Посмотреть сообщение
Куча опечаток, заметных, если присмотреться.
Ткните носом, пожалуйста! =)
Цитата Сообщение от easybudda Посмотреть сообщение
main() всё-таки должна иметь тип int
Исправил!

Прошу прощения за занудность, но проблема не решилась...
После того, как дописал typedef перед объявлением структуры, стало выдавать ошибки в строках 64, 68 и т.д... Пишет E2108 Improper use of typedef 'people'
Подскажите, как бороться?
0
Каратель
Эксперт С++
6609 / 4028 / 401
Регистрация: 26.03.2010
Сообщений: 9,273
Записей в блоге: 1
13.06.2012, 22:46 8
Цитата Сообщение от razer89 Посмотреть сообщение
Без него ругается на строку
для strcpy нужен string.h, а не iostream

Добавлено через 1 минуту
Цитата Сообщение от razer89 Посмотреть сообщение
Посоветуйте, как поступить в конкретном случае, чтобы избавиться от внешней переменной?
передавать FILE* аргументом функции
1
15 / 15 / 0
Регистрация: 20.06.2010
Сообщений: 142
13.06.2012, 22:51  [ТС] 9
Цитата Сообщение от Jupiter Посмотреть сообщение
для strcpy нужен string.h, а не iostream
Спасибо, исправил.
Цитата Сообщение от Jupiter Посмотреть сообщение
передавать FILE* аргументом функции
Можно подробней? Заранее благодарен!
0
Эксперт С++
2381 / 1665 / 279
Регистрация: 29.05.2011
Сообщений: 3,399
13.06.2012, 23:22 10
Цитата Сообщение от razer89 Посмотреть сообщение
Цитата Сообщение от Jupiter Посмотреть сообщение
передавать FILE* аргументом функции
Можно подробней? Заранее благодарен!
Ну, в данном случае этого не нужно. Просто глобальную переменную database убить и объявить в каждой функции, где она используется. А ещё в функции sort файл надо закрыть, видимо.

Добавлено через 4 минуты
А вот с people надо всё-таки определиться. В основном она как переменная используется, но в функциях сравнения она вдруг используется как тип. Так это тип или переменная?
0
15 / 15 / 0
Регистрация: 20.06.2010
Сообщений: 142
13.06.2012, 23:42  [ТС] 11
Цитата Сообщение от grizlik78 Посмотреть сообщение
Так это тип или переменная?
Это переменная. Не совсем понял, почему она используется в функциях сравнения, как тип.
0
Эксперт С++
2381 / 1665 / 279
Регистрация: 29.05.2011
Сообщений: 3,399
13.06.2012, 23:48 12
ну вот это:
(people*)a
это преобразование типа переменной a к указателю на people. Здесь people может быть только типом.
0
15 / 15 / 0
Регистрация: 20.06.2010
Сообщений: 142
14.06.2012, 00:18  [ТС] 13
Цитата Сообщение от grizlik78 Посмотреть сообщение
(people*)a
это я взял из примера от easybudda, как оно работает я пока не разобрался...))
может подскажете, как будет правильно?
0
Эксперт С++
2381 / 1665 / 279
Регистрация: 29.05.2011
Сообщений: 3,399
14.06.2012, 00:24 14
razer89, а я это взял из самого первого поста, ещё до easybudda
Лучше тогда всё-таки объявить тип с этой структурой с каким-нибудь другим именем. Например с большой буквы, или суффикс _t прибавить, или ёщё как.
C
1
2
3
4
5
typedef struct {
    char FIO [25];
    float s2;
    int amount;
} People;
А потом уже там где надо создавать переменную:
C
1
People people;
Ну а там где надо преобразование, там использовать тип
C
1
(People*)a
1
Модератор
Эксперт PythonЭксперт JavaЭксперт CЭксперт С++
12438 / 7465 / 1749
Регистрация: 25.07.2009
Сообщений: 13,721
14.06.2012, 01:09 15
Лучший ответ Сообщение было отмечено Памирыч как решение

Решение

razer89, при работе с файлами проверок много не бывает. По-хорошему нужно проверять всё, что проверяется. Писать полностью по заданию мне лень, вот пример из заголовка и двух програмок - одна в файл пишет, другая из него читает и сортирует по-всякому:


persons.h
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
#ifndef _PERSONS_H_
#define _PERSONS_H_ 1
 
#include <string.h>
 
#define NAME_LENGTH 32
#define DB_FILE "persons.db"
 
typedef struct PERSON {
    char   name[NAME_LENGTH];
    int    growth;
    double weight;
} person_t;
 
int name_cmp(const void * a, const void *b) {
    return strcmp(((person_t*)a)->name, ((person_t*)b)->name);
}
 
int growth_cmp(const void * a, const void * b) {
    return ((person_t*)a)->growth - ((person_t*)b)->growth;
}
 
int weight_cmp(const void * a, const void * b) {
    double d = ((person_t*)a)->weight - ((person_t*)b)->weight;
    return ( d < 0.0 ) ? -1 : ( d > 0.0 ) ? 1 : 0;
}
 
void dump(const person_t * pPerson) {
    printf("%-20s %6d %6.1f\n", pPerson->name, pPerson->growth, pPerson->weight);
}
 
#endif /* _PERSONS_H_ */


persons_write.c
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
#include <stdio.h>
#include <stdlib.h>
#include "persons.h"
 
#define NUM_PERSONS 3
 
int main(void) {
    person_t persons[NUM_PERSONS] = {
        { "Sidorov", 178, 98.9 },
        { "Petrov", 182, 78.5 },
        { "Ivanov", 185, 79.2 }
    };
    FILE * f;
    
    if ( ! ( f = fopen(DB_FILE, "wb") ) ) {
        perror("fopen");
        exit(1);
    }
    
    if ( fwrite(persons, sizeof(person_t), NUM_PERSONS, f) != NUM_PERSONS ) {
        fprintf(stderr, "Can't write to db file.\n");
        if ( fclose(f) )
            perror("fclose");
        exit(1);
    }
    
    if ( fclose(f) ) {
        perror("fclose");
        exit(1);
    }
    
    fprintf(stderr, "Wrote information for %u persons.\n", NUM_PERSONS);
    
    exit(0);
}


persons_read.c
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
#include <stdio.h>
#include <stdlib.h>
#include "persons.h"
 
int main(void) {
    FILE * f;
    long nFileLength;
    person_t * pPersons;
    size_t i, nPersons;
    
    if ( ! ( f = fopen(DB_FILE, "rb") ) ) {
        perror("fopen");
        exit(1);
    }
    
    if ( fseek(f, 0, SEEK_END) ) {
        perror("fseek");
        if ( fclose(f) )
            perror("fclose");
        exit(1);
    }
    if ( ( nFileLength = ftell(f) ) < 0 ) {
        perror("ftell");
        if ( fclose(f) )
            perror("fclose");
        exit(1);
    }
    if ( nFileLength == 0 ) {
        fprintf(stderr, "DB file is empty.\n");
        if ( fclose(f) )
            perror("fclose");
        exit(1);
    }
    if ( nFileLength % sizeof(person_t) ) {
        fprintf(stderr, "DB file is corrupt!\n");
        if ( fclose(f) )
            perror("fclose");
        exit(1);
    }
    rewind(f);
    
    nPersons = nFileLength / sizeof(person_t);
    if ( ! ( pPersons = malloc(sizeof(person_t) * nPersons) ) ) {
        perror("malloc");
        if ( fclose(f) )
            perror("fclose");
        exit(1);
    }
    if ( fread(pPersons, sizeof(person_t), nPersons, f) != nPersons ) {
        fprintf(stderr, "Can't read from DB file.\n");
        if ( fclose(f) )
            perror("fclose");
        exit(1);
    }
    
    if ( fclose(f) ) {
        perror("fclose");
        exit(1);
    }
    
    printf("By name:\n");
    qsort(pPersons, nPersons, sizeof(person_t), name_cmp);
    for ( i = 0; i < nPersons; ++i )
        dump(&pPersons[i]);
    
    printf("\nBy growth:\n");
    qsort(pPersons, nPersons, sizeof(person_t), growth_cmp);
    for ( i = 0; i < nPersons; ++i )
        dump(&pPersons[i]);
    
    printf("\nBy weight:\n");
    qsort(pPersons, nPersons, sizeof(person_t), weight_cmp);
    for ( i = 0; i < nPersons; ++i )
        dump(&pPersons[i]);
    
    free(pPersons);
    
    exit(0);
}
Сортировка массив структур: qsort выдает Expression syntax
1
15 / 15 / 0
Регистрация: 20.06.2010
Сообщений: 142
14.06.2012, 01:50  [ТС] 16
easybudda, спасибо большое за примеры. Код поправил, теперь он начал компилироваться)) Но работать он все равно почему-то не хочет... Вот что добавил в коде:
C
1
2
typedef struct people {char FIO [25]; float s2; int amount;} people_t;
people_t * Peoples;
Но теперь программа вываливается вот на этом месте, при вызове функции view_all, с ошибкой Access Violation:
C
1
2
3
4
5
void add_item()
{
    database = fopen ("database.db", "ab");
    puts ("Input FIO");
    scanf ("%s", Peoples->FIO);
Что опять не так?...
0
Эксперт С++
2381 / 1665 / 279
Регистрация: 29.05.2011
Сообщений: 3,399
14.06.2012, 01:55 17
Здесь Peoples это указатель. Но он, похоже, указывает в никуда. Память-то под эту структуру где-нибудь выделялась?
1
15 / 15 / 0
Регистрация: 20.06.2010
Сообщений: 142
14.06.2012, 03:05  [ТС] 18
grizlik78, кажется, я понял, в чем ошибка... Сейчас поправлю!

Добавлено через 1 час 7 минут
grizlik78, easybudda, огромное вам человеческое спасибо! Разобрался!
Все дело было в том, что я путал понятия ТИПА и самой ПЕРЕМЕННОЙ, также у меня беда с указателями (позор мне...). Буду учиться! Спасибо еще раз!
Если кому интересно, могу позже выложить весь код.
1
Модератор
Эксперт PythonЭксперт JavaЭксперт CЭксперт С++
12438 / 7465 / 1749
Регистрация: 25.07.2009
Сообщений: 13,721
14.06.2012, 03:25 19
Цитата Сообщение от razer89 Посмотреть сообщение
могу позже выложить весь код.
Обязательно выкладывайте! Наверняка узнаете ещё много нового...
1
15 / 15 / 0
Регистрация: 20.06.2010
Сообщений: 142
14.06.2012, 20:33  [ТС] 20
Ребят, еще такой вопрос. Как реализовать удаление определенных структур из файла? Записывать новые знаю как, а вот с удалением не могу разобраться...
0
14.06.2012, 20:33
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
14.06.2012, 20:33
Помогаю со студенческими работами здесь

Qsort() для сортировки структур по дате (struct tm)
Здравствуйте. Стоит задача отсортировать массив структур timetable, одно из поле которой -...

Блочная сортировка структур (Отсортировать массив структур по фамилии)
Подскажите алгоритм блочной сортировки структур на языке С++. Мне нужно отсортировать массив...

Выдает ошибку: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '
Привет, форумчане, возникла проблема с кодом Php. Написал код для кнопки лайков на сайте, а выдает...

Qsort для массива структур
Да, знаю, что таких тем на форуме уже полно, как и кода, но смысл мне всё равно непонятен. Есть...


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

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

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru