Форум программистов, компьютерный форум, киберфорум
Наши страницы
C для начинающих
Войти
Регистрация
Восстановить пароль
 
Рейтинг 4.67/3: Рейтинг темы: голосов - 3, средняя оценка - 4.67
Loinch
13 / 6 / 2
Регистрация: 25.03.2014
Сообщений: 89
1

Не компиллируется код Си. Образец с rosettacode

26.03.2014, 11:32. Просмотров 593. Ответов 11
Метки нет (Все метки)

Доброго времени!

Прошу помочь преобразовать код так, чтобы можно было собрать образец, представленный на Rosettacode К сожалению, моих знаний недостаточно, чтобы решить проблему.

Если исключить в коде все упоминания сортировки по дате (by_date), то всё замечательно собирается и работает.

Пробовал и GCC, и clang. Результат идентичный:

GCC version 4.8.1 (Ubuntu/Linaro 4.8.1-10ubuntu9):

Bash
1
2
3
4
5
6
7
8
9
gcc simple-database.c -o simple-database
 
simple-database.c:188:12: error: conflicting types for ‘by_date’
static int by_date (pdb_t *p1, pdb_t *p2) {
           ^
simple-database.c:31:13: note: previous declaration of ‘by_date’ was here
static sort by_date;
            ^
simple-database.c:31:13: warning: ‘by_date’ used but never defined [enabled by default]
clang version 3.2-7ubuntu1 (tags/RELEASE_32/final) (based on LLVM 3.2) give the same result:
Bash
1
2
3
4
5
6
7
8
9
clang simple-database.c -o simple-database
 
simple-database.c:188:12: error: conflicting types for 'by_date'
static int by_date (pdb_t *p1, pdb_t *p2) {
          ^
simple-database.c:31:13: note: previous declaration is here
static sort by_date;
           ^
1 error generated.
Код программы и файл CSV

Файл database.csv

CSS
1
2
3
4
5
6
7
"Soon Rising","Dee","Lesace","10-12-2000","New Hat Press"
"Brave Chicken","Tang","Owe","04-01-2008","Nowhere Press"
"Aardvark Point","Dee","Lesace","5-24-2001","New Hat Press"
"Bat Whisperer, The","Tang","Owe","01-03-2004","Nowhere Press"
"Treasure Beach","Argus","Jemky","09-22-1999","Lancast"
"ololo1","autor","lastname","12-31-1899","sdfasdfa" 
"dfgsdfgsfd","sdfgsdfg","sdfgsdfg","01-02-2014","sdfgsdfg"
Файл simple-database.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
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
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
#include <stdio.h>
#include <stdlib.h> /* malloc */
#include <string.h> /* strlen */
#define _XOPEN_SOURCE /* requred for time functions */
#define __USE_XOPEN
#include <time.h>
#define DB "database.csv" /* database name */
#define TRY(a)  if (!(a)) {perror(#a);exit(1);}
#define TRY2(a) if((a)<0) {perror(#a);exit(1);}
#define FREE(a) if(a) {free(a);a=NULL;}
#define sort_by(foo) \
static int by_##foo (const void*p1, const void*p2) { \
    return strcmp ((*(const pdb_t*)p1)->foo, (*(const pdb_t*)p2)->foo); }
typedef struct db {
    char title[26];
    char first_name[26];
    char last_name[26];
    time_t date;
    char publ[100];
    struct db *next;
}
db_t,*pdb_t;
typedef int (sort)(const void*, const void*);
enum {CREATE,PRINT,TITLE,DATE,AUTH,READLINE,READ,SORT,DESTROY};
static pdb_t dao (int cmd, FILE *f, pdb_t db, sort sortby);
static char *time2str (time_t *time);
static time_t str2time (char *date);
/* qsort callbacks */
sort_by(last_name);
sort_by(title);
static sort by_date;
/* main */
int main (int argc, char **argv) {
    char buf[100];
    const char *commands[]={"-c", "-p", "-t", "-d", "-a", NULL};
    db_t db;
    db.next=NULL;
    pdb_t dblist;
    int i;
    FILE *f;
    TRY (f=fopen(DB,"a+"));
    if (argc<2) {
usage:  printf ("Usage: %s [commands]\n"
        "-c  Create new entry.\n"
        "-p  Print the latest entry.\n"
        "-t  Print all entries sorted by title.\n"
        "-d  Print all entries sorted by date.\n"
        "-a  Print all entries sorted by author.\n",argv[0]);
        fclose (f);
        return 0;
    }
    for (i=0;commands[i]&&strcmp(argv[1],commands[i]);i++);
    switch (i) {
        case CREATE:
        printf("-c  Create a new entry.\n");
        printf("Title           :");if((scanf(" %25[^\n]",db.title     ))<0)break;
        printf("Author Firstname:");if((scanf(" %25[^\n]",db.first_name))<0)break;
        printf("Author Lastname :");if((scanf(" %25[^\n]",db.last_name ))<0)break;
        printf("Date 10-12-2000 :");if((scanf(" %10[^\n]",buf          ))<0)break;
        printf("Publication     :");if((scanf(" %99[^\n]",db.publ      ))<0)break;
        db.date=str2time (buf);
        dao (CREATE,f,&db,NULL);
        break;
        case PRINT:
        printf ("-p  Print the latest entry.\n");
        while (!feof(f)) dao (READLINE,f,&db,NULL);
        dao (PRINT,f,&db,NULL);
        break;
        case TITLE:
        printf ("-t  Print all entries sorted by title.\n");
        dblist = dao (READ,f,&db,NULL);
        dblist = dao (SORT,f,dblist,by_title);
        dao (PRINT,f,dblist,NULL);
        dao (DESTROY,f,dblist,NULL);
        break;
        case DATE:
        printf ("-d  Print all entries sorted by date.\n");
        dblist = dao (READ,f,&db,NULL);
        dblist = dao (SORT,f,dblist,by_date);
        dao (PRINT,f,dblist,NULL);
        dao (DESTROY,f,dblist,NULL);
        break;
        case AUTH:
        printf ("-a  Print all entries sorted by author.\n");
        dblist = dao (READ,f,&db,NULL);
        dblist = dao (SORT,f,dblist,by_last_name);
        dao (PRINT,f,dblist,NULL);
        dao (DESTROY,f,dblist,NULL);
        break;
        default: {
            printf ("Unknown command: %s.\n",strlen(argv[1])<10?argv[1]:"");
            goto usage;
    }   }
    fclose (f);
    return 0;
}
/* Data Access Object (DAO) */
static pdb_t dao (int cmd, FILE *f, pdb_t in_db, sort sortby) {
    pdb_t *pdb=NULL,rec=NULL,hd=NULL;
    int i=0,ret;
    char buf[100];
    switch (cmd) {
        case CREATE:
        fprintf (f,"\"%s\",",in_db->title);
        fprintf (f,"\"%s\",",in_db->first_name);
        fprintf (f,"\"%s\",",in_db->last_name);
        fprintf (f,"\"%s\",",time2str(&in_db->date));
        fprintf (f,"\"%s\" \n",in_db->publ);
        break;
        case PRINT:
        for (;in_db;i++) {
            printf ("Title       : %s\n",     in_db->title);
            printf ("Author      : %s %s\n",  in_db->first_name, in_db->last_name);
            printf ("Date        : %s\n",     time2str(&in_db->date));
            printf ("Publication : %s\n\n",   in_db->publ);
            if (!((i+1)%3)) {
                printf ("Press Enter to continue.\n");
                ret = scanf ("%*[^\n]");
                if (ret<0) return rec; /* handle EOF */
                else getchar();
            }
            in_db=in_db->next;
        }
        break;
        case READLINE:
        if((fscanf(f," \"%[^\"]\",",in_db->title     ))<0)break;
        if((fscanf(f," \"%[^\"]\",",in_db->first_name))<0)break;
        if((fscanf(f," \"%[^\"]\",",in_db->last_name ))<0)break;
        if((fscanf(f," \"%[^\"]\",",buf              ))<0)break;
        if((fscanf(f," \"%[^\"]\" ",in_db->publ      ))<0)break;
        in_db->date=str2time (buf);
        break;
        case READ:
        while (!feof(f)) {
            dao (READLINE,f,in_db,NULL);
            TRY (rec=malloc(sizeof(db_t)));
            *rec=*in_db; /* copy contents */
            rec->next=hd;/* to linked list */
            hd=rec;i++;
        }
        if (i<2) {
            puts ("Empty database. Please create some entries.");
            fclose (f);
            exit (0);
        }
        break;
        case SORT:
        rec=in_db;
        for (;in_db;i++) in_db=in_db->next;
        TRY (pdb=malloc(i*sizeof(pdb_t)));
        in_db=rec;
        for (i=0;in_db;i++) {
            pdb[i]=in_db;
            in_db=in_db->next;
        }
        qsort (pdb,i,sizeof in_db,sortby);
        pdb[i-1]->next=NULL;
        for (;i;i--) {
            pdb[i-1]->next=pdb[i];
        }
        rec=pdb[0];
        FREE (pdb);
        pdb=NULL;
        break;
        case DESTROY: {
            while ((rec=in_db)) {
                in_db=in_db->next;
                FREE (rec);
    }   }   }
    return rec;
}
/* convert numeric time to date string */
static char *time2str (time_t *time) {
    static char buf[255];
    struct tm *ptm;
    ptm=localtime (time);
    strftime(buf, 255, "%m-%d-%Y", ptm);
    return buf;
}
/* convert date string to numeric time */
static time_t str2time (char *date) {
    struct tm tm;
    memset (&tm, 0, sizeof(struct tm));
    strptime(date, "%m-%d-%Y", &tm);
    return mktime(&tm);
}
/* sort by date callback for qsort */
static int by_date (pdb_t *p1, pdb_t *p2) {
    if ((*p1)->date < (*p2)->date) {
        return -1;
    }
    else return ((*p1)->date > (*p2)->date);
}
Розетчикам о баге сообщил, но увы, реакции не последовало.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
26.03.2014, 11:32
Ответы с готовыми решениями:

Почему код не компиллируется без преобразования
class A { public: void foo() { } }; class B : public A { };

Не компиллируется функция cout
В DevC++ не компиллируется программа с функцией cout. #include &lt;iostream.h&gt; ...

DevC++ не компиллируется ни один проект
Проблема появилась после того, как я удалил некоторые системные переменные из...

Не компиллируется прога - ошибка в объявлении переменных?
Имеется программа на Visual Prolog 5.2, реализующая составление кроссворда из...

Образец программы на с++
завтра олимпиада и помогите подготовиться =) как оформлять прогу на с++ =) где...

11
Vtulhu
423 / 377 / 200
Регистрация: 12.08.2011
Сообщений: 1,610
26.03.2014, 11:42 2
Оба компилятора говорят об одном и том же, надо лишь внимательно прочитать. Или хотя бы внимательно посмотреть на строки, которые в этих сообщениях упоминаются (31 и 188). Очевидно, это просто опечатка.
0
Loinch
13 / 6 / 2
Регистрация: 25.03.2014
Сообщений: 89
26.03.2014, 12:05  [ТС] 3
Я честно пытался решить проблему самостоятельно. Прибегал к раскрытию define и typedef для улучшения читабельности, но увы, пофиксить баг не удалось. В сишке я начинающий.

Предполагаю, что нужно преобразовывать типы, но все мои эксперименты не увенчались успехом. Прибегаю к помощи как к крайней мере.
0
Vtulhu
423 / 377 / 200
Регистрация: 12.08.2011
Сообщений: 1,610
26.03.2014, 12:14 4
Вы бы еще в бубен шаманский постучали. Посмотрите внимательно на вышеупомянутые строки:

C
1
2
3
static sort by_date; // 31
 
static int by_date (pdb_t *p1, pdb_t *p2) { // 188
В первой объявляется переменная by_date типа sort. Однако потом такая переменная нигде не используется. И типа sort у нас нет, кстати. В другой строке объявляется функция by_date(), которая используется, но нигде не объявлена. Не возникает подозрения, что это все как-то взаимосвязано?
1
Loinch
13 / 6 / 2
Регистрация: 25.03.2014
Сообщений: 89
26.03.2014, 12:24  [ТС] 5
Цитата Сообщение от Vtulhu Посмотреть сообщение
И типа sort у нас нет, кстати
Извините, но есть:
C
1
typedef int (sort)(const void*, const void*);
Цитата Сообщение от Vtulhu Посмотреть сообщение
Не возникает подозрения, что это все как-то взаимосвязано?
Замена

C
1
static int by_date (pdb_t *p1, pdb_t *p2) { // 188
на

C
1
static sort by_date (pdb_t *p1, pdb_t *p2) { // 188
Положительного действия, естественно, не возымели. Поэтому, собственно, и обратился к помощи сведущих.
0
Vtulhu
423 / 377 / 200
Регистрация: 12.08.2011
Сообщений: 1,610
26.03.2014, 12:53 6
Наоборот надо было, в 31 строке заменить sort на int. Функции семейства by_что-то-там нужны для сортировки. Они выдают число -1, 0 или 1 в зависимости от того, как соотносятся между собой первый и второй аргумент. ИМХО, разработчики перемудрили. Я бы раскрыл дефайн sort_by(foo). Да, он избавлял нас от повторяющегося кода. Но он повторяется всего два раза. И повторяется код длиной в одну строку! При этом мы усложняем программу, вводя разные способы объявления функций для разных типов сортировки. Строки сортируются через дефайн, а даты - через функцию, объявленную обычным способом.
0
Loinch
13 / 6 / 2
Регистрация: 25.03.2014
Сообщений: 89
27.03.2014, 11:31  [ТС] 7
Попробую переделать как Вы рекомендуете. Хотя странно, наверняка раньше код компилировался и работал. Срабатывало неявное приведение типов?

О результате отпишусь.

Добавлено через 1 минуту
1. Раскрыл typedef
2. Функция by_date() принимает переменные одного типа, а qsort может ей скормить другого типа, поэтому сделал приведение типа по статье "Язык Си в примерах/Сортировка", глава "Программа упорядочения строк в алфавитном порядке" , НО...
3. Программа компиллируется без ворнингов
4. При исполнении программы сортировка по дате происходит нормально, но программа при любых вариантах завершается с Segmentation fault (core dumped)

Вот получившийся код:

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
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
#include <stdio.h>
#include <stdlib.h> /* malloc */
#include <string.h> /* strlen */
#define _XOPEN_SOURCE /* requred for time functions */
#define __USE_XOPEN
#include <time.h>
#define DB "database.csv" /* database name */
#define TRY(a)  if (!(a)) {perror(#a);exit(1);}
#define TRY2(a) if((a)<0) {perror(#a);exit(1);}
#define FREE(a) if(a) {free(a);a=NULL;}
#define sort_by(foo) \
static int by_##foo (const void*p1, const void*p2) { \
    return strcmp ((*(const pdb_t*)p1)->foo, (*(const pdb_t*)p2)->foo); }
typedef struct db {
    char title[26];
    char first_name[26];
    char last_name[26];
    time_t date;
    char publ[100];
    struct db *next;
}
db_t,*pdb_t;
//typedef int (sort)(const void*, const void*);
enum {CREATE,PRINT,TITLE,DATE,AUTH,READLINE,READ,SORT,DESTROY};
static pdb_t dao (int cmd, FILE *f, pdb_t db, int sortby(const void*, const void*));
static char *time2str (time_t *time);
static time_t str2time (char *date);
/* qsort callbacks */
sort_by(last_name);
sort_by(title);
static int by_date(const pdb_t*,const pdb_t*);
/* main */
int main (int argc, char **argv) {
    char buf[100];
    const char *commands[]={"-c", "-p", "-t", "-d", "-a", NULL};
    db_t db;
    db.next=NULL;
    pdb_t dblist;
    int i;
    FILE *f;
    TRY (f=fopen(DB,"a+"));
    if (argc<2) {
usage:  printf ("Usage: %s [commands]\n"
        "-c  Create new entry.\n"
        "-p  Print the latest entry.\n"
        "-t  Print all entries sorted by title.\n"
        "-d  Print all entries sorted by date.\n"
        "-a  Print all entries sorted by author.\n",argv[0]);
        fclose (f);
        return 0;
    }
    for (i=0;commands[i]&&strcmp(argv[1],commands[i]);i++);
    switch (i) {
        case CREATE:
        printf("-c  Create a new entry.\n");
        printf("Title           :");if((scanf(" %25[^\n]",db.title     ))<0)break;
        printf("Author Firstname:");if((scanf(" %25[^\n]",db.first_name))<0)break;
        printf("Author Lastname :");if((scanf(" %25[^\n]",db.last_name ))<0)break;
        printf("Date 10-12-2000 :");if((scanf(" %10[^\n]",buf          ))<0)break;
        printf("Publication     :");if((scanf(" %99[^\n]",db.publ      ))<0)break;
        db.date=str2time (buf);
        dao (CREATE,f,&db,NULL);
        break;
        case PRINT:
        printf ("-p  Print the latest entry.\n");
        while (!feof(f)) dao (READLINE,f,&db,NULL);
        dao (PRINT,f,&db,NULL);
        break;
        case TITLE:
        printf ("-t  Print all entries sorted by title.\n");
        dblist = dao (READ,f,&db,NULL);
        dblist = dao (SORT,f,dblist,by_title);
        dao (PRINT,f,dblist,NULL);
        dao (DESTROY,f,dblist,NULL);
        break;
        case DATE:
        printf ("-d  Print all entries sorted by date.\n");
        dblist = dao (READ,f,&db,NULL);
        dblist = dao (SORT,f,dblist,(int (*)(const void *,const  void *))by_date);
        dao (PRINT,f,dblist,NULL);
        dao (DESTROY,f,dblist,NULL);
        break;
        case AUTH:
        printf ("-a  Print all entries sorted by author.\n");
        dblist = dao (READ,f,&db,NULL);
        dblist = dao (SORT,f,dblist,by_last_name);
        dao (PRINT,f,dblist,NULL);
        dao (DESTROY,f,dblist,NULL);
        break;
        default: {
            printf ("Unknown command: %s.\n",strlen(argv[1])<10?argv[1]:"");
            goto usage;
    }   }
    fclose (f);
    return 0;
}
/* Data Access Object (DAO) */
static pdb_t dao (int cmd, FILE *f, pdb_t in_db, int sortby(const void*, const void*)) {
    pdb_t *pdb=NULL,rec=NULL,hd=NULL;
    int i=0,ret;
    char buf[100];
    switch (cmd) {
        case CREATE:
        fprintf (f,"\"%s\",",in_db->title);
        fprintf (f,"\"%s\",",in_db->first_name);
        fprintf (f,"\"%s\",",in_db->last_name);
        fprintf (f,"\"%s\",",time2str(&in_db->date));
        fprintf (f,"\"%s\" \n",in_db->publ);
        break;
        case PRINT:
        for (;in_db;i++) {
            printf ("Title       : %s\n",     in_db->title);
            printf ("Author      : %s %s\n",  in_db->first_name, in_db->last_name);
            printf ("Date        : %s\n",     time2str(&in_db->date));
            printf ("Publication : %s\n\n",   in_db->publ);
            if (!((i+1)%3)) {
                printf ("Press Enter to continue.\n");
                ret = scanf ("%*[^\n]");
                if (ret<0) return rec; /* handle EOF */
                else getchar();
            }
            in_db=in_db->next;
        }
        break;
        case READLINE:
        if((fscanf(f," \"%[^\"]\",",in_db->title     ))<0)break;
        if((fscanf(f," \"%[^\"]\",",in_db->first_name))<0)break;
        if((fscanf(f," \"%[^\"]\",",in_db->last_name ))<0)break;
        if((fscanf(f," \"%[^\"]\",",buf              ))<0)break;
        if((fscanf(f," \"%[^\"]\" ",in_db->publ      ))<0)break;
        in_db->date=str2time (buf);
        break;
        case READ:
        while (!feof(f)) {
            dao (READLINE,f,in_db,NULL);
            TRY (rec=malloc(sizeof(db_t)));
            *rec=*in_db; /* copy contents */
            rec->next=hd;/* to linked list */
            hd=rec;i++;
        }
        if (i<2) {
            puts ("Empty database. Please create some entries.");
            fclose (f);
            exit (0);
        }
        break;
        case SORT:
        rec=in_db;
        for (;in_db;i++) in_db=in_db->next;
        TRY (pdb=malloc(i*sizeof(pdb_t)));
        in_db=rec;
        for (i=0;in_db;i++) {
            pdb[i]=in_db;
            in_db=in_db->next;
        }
        qsort (pdb,i,sizeof in_db,sortby);
        pdb[i-1]->next=NULL;
        for (;i;i--) {
            pdb[i-1]->next=pdb[i];
        }
        rec=pdb[0];
        FREE (pdb);
        pdb=NULL;
        break;
        case DESTROY: {
            while ((rec=in_db)) {
                in_db=in_db->next;
                FREE (rec);
    }   }   }
    return rec;
}
/* convert numeric time to date string */
static char *time2str (time_t *time) {
    static char buf[255];
    struct tm *ptm;
    ptm=localtime (time);
    strftime(buf, 255, "%m-%d-%Y", ptm);
    return buf;
}
/* convert date string to numeric time */
static time_t str2time (char *date) {
    struct tm tm;
    memset (&tm, 0, sizeof(struct tm));
    strptime(date, "%m-%d-%Y", &tm);
    return mktime(&tm);
}
/* sort by date callback for qsort */
static int by_date (const pdb_t *p1,const pdb_t *p2) {
    if ((*p1)->date < (*p2)->date) {
        return -1;
    }
    else return ((*p1)->date > (*p2)->date);
}
0
Vtulhu
423 / 377 / 200
Регистрация: 12.08.2011
Сообщений: 1,610
27.03.2014, 12:14 8
У меня такой совет. Храните время не как структуру типа time_t, а в виде строки. Например, вот так: "2014-03-27 12:03:59". Или "20140327", если время не важно. Это очень сильно упростит программу, потому что позволит сортировать по времени точно так же, как и по остальным параметрам, т.е. с помощью strcmp.

И перепишите код, разбив его на как можно большее количество маленьких, простых, независимых частей.
0
easybudda
Модератор
Эксперт CЭксперт С++
10115 / 6023 / 1510
Регистрация: 25.07.2009
Сообщений: 11,418
27.03.2014, 16:24 9
Цитата Сообщение от Vtulhu Посмотреть сообщение
Храните время не как структуру типа time_t, а в виде строки.
Эта, как Вы выразились, "структура" на самом деле переменная целочисленного типа, а следовательно две таких переменных вполне можно сравнивать. Структура - struct tm, другая история...
0
Vtulhu
423 / 377 / 200
Регистрация: 12.08.2011
Сообщений: 1,610
27.03.2014, 17:02 10
Так это же еще проще! Надо хранить дату в виде строкового представления этого числа. Только строки должны быть обязательно одинаковой длины. Я сейчас посмотрел внимательно в time.h - действительно, time_t всего лишь число. Но в общем случае неизвестной разрядности. Если топикстартера это не смущает (например, он точно знает, что всегда будет использовать 32-битный формат), то все упрощается до невозможности. Конвертируем это 32-битное значение в строковую запись типа такой: "A534563BC". Если нужна совместимость между 32-битным и 64-битным представлением времени, задача немного усложняется.
0
Loinch
13 / 6 / 2
Регистрация: 25.03.2014
Сообщений: 89
28.03.2014, 12:58  [ТС] 11
Ради эксперимента в немодифицированном файле закомментировал все участки, относящиеся к функции by_date() И что интересно, программа тоже отрабатывает, но завершается с сообщением Segmentation fault (core dumped)

Где ещё копать причину кроме by_date()?

Добавлено через 19 часов 28 минут
Методом исключения удалось выяснить, что к Segmentation fault (core dumped) приводит строка 153. Как в этом случае должно быть правильно, чтобы программа работала корректно? Вот код, получившийся в результате. Проблемная строка закомментирована.

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
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
#include <stdio.h>
#include <stdlib.h> /* malloc */
#include <string.h> /* strlen */
#define _XOPEN_SOURCE /* requred for time functions */
#define __USE_XOPEN
#include <time.h>
#define DB "database.csv" /* database name */
#define TRY(a)  if (!(a)) {perror(#a);exit(1);}
#define TRY2(a) if((a)<0) {perror(#a);exit(1);}
#define FREE(a) if(a) {free(a);a=NULL;}
#define sort_by(foo) \
static int by_##foo (const void*p1, const void*p2) { \
    return strcmp ((*(const pdb_t*)p1)->foo, (*(const pdb_t*)p2)->foo); }
typedef struct db {
    char title[26];
    char first_name[26];
    char last_name[26];
    time_t date;
    char publ[100];
    struct db *next;
}
db_t,*pdb_t;
typedef int (sort)(const void*, const void*);
enum {CREATE,PRINT,TITLE,DATE,AUTH,READLINE,READ,SORT,DESTROY};
static pdb_t dao (int cmd, FILE *f, pdb_t db, sort sortby);
static char *time2str (time_t *time);
static time_t str2time (char *date);
/* qsort callbacks */
sort_by(last_name);
sort_by(title);
//static sort by_date;
/* main */
int main (int argc, char **argv) {
    char buf[100];
    const char *commands[]={"-c", "-p", "-t", "-d", "-a", NULL};
    db_t db;
    db.next=NULL;
    pdb_t dblist;
    int i;
    FILE *f;
    TRY (f=fopen(DB,"a+"));
    if (argc<2) {
usage:  printf ("Usage: %s [commands]\n"
        "-c  Create new entry.\n"
        "-p  Print the latest entry.\n"
        "-t  Print all entries sorted by title.\n"
        "-d  Print all entries sorted by date.\n"
        "-a  Print all entries sorted by author.\n",argv[0]);
        fclose (f);
        return 0;
    }
    for (i=0;commands[i]&&strcmp(argv[1],commands[i]);i++);
    switch (i) {
        case CREATE:
        printf("-c  Create a new entry.\n");
        printf("Title           :");if((scanf(" %25[^\n]",db.title     ))<0)break;
        printf("Author Firstname:");if((scanf(" %25[^\n]",db.first_name))<0)break;
        printf("Author Lastname :");if((scanf(" %25[^\n]",db.last_name ))<0)break;
        printf("Date 10-12-2000 :");if((scanf(" %10[^\n]",buf          ))<0)break;
        printf("Publication     :");if((scanf(" %99[^\n]",db.publ      ))<0)break;
        db.date=str2time (buf);
        dao (CREATE,f,&db,NULL);
        break;
        case PRINT:
        printf ("-p  Print the latest entry.\n");
        while (!feof(f)) dao (READLINE,f,&db,NULL);
        dao (PRINT,f,&db,NULL);
        break;
        case TITLE:
        printf ("-t  Print all entries sorted by title.\n");
        dblist = dao (READ,f,&db,NULL);
        dblist = dao (SORT,f,dblist,by_title);
        dao (PRINT,f,dblist,NULL);
        dao (DESTROY,f,dblist,NULL);
        break;
/*        case DATE:
        printf ("-d  Print all entries sorted by date.\n");
        dblist = dao (READ,f,&db,NULL);
        dblist = dao (SORT,f,dblist,by_date);
        dao (PRINT,f,dblist,NULL);
        dao (DESTROY,f,dblist,NULL);
        break;
*/        case AUTH:
        printf ("-a  Print all entries sorted by author.\n");
        dblist = dao (READ,f,&db,NULL);
        dblist = dao (SORT,f,dblist,by_last_name);
        dao (PRINT,f,dblist,NULL);
        dao (DESTROY,f,dblist,NULL);
        break;
        default: {
            printf ("Unknown command: %s.\n",strlen(argv[1])<10?argv[1]:"");
            goto usage;
    }   }
    fclose (f);
    return 0;
}
/* Data Access Object (DAO) */
static pdb_t dao (int cmd, FILE *f, pdb_t in_db, sort sortby) {
    pdb_t *pdb=NULL,rec=NULL,hd=NULL;
    int i=0;
    char buf[100];
    switch (cmd) {
        case CREATE:
        fprintf (f,"\"%s\",",in_db->title);
        fprintf (f,"\"%s\",",in_db->first_name);
        fprintf (f,"\"%s\",",in_db->last_name);
        fprintf (f,"\"%s\",",time2str(&in_db->date));
        fprintf (f,"\"%s\" \n",in_db->publ);
        break;
        case PRINT:
        for (;in_db;i++) {
            printf ("Title       : %s\n",     in_db->title);
            printf ("Author      : %s %s\n",  in_db->first_name, in_db->last_name);
            printf ("Date        : %s\n",     time2str(&in_db->date));
            printf ("Publication : %s\n\n",   in_db->publ);
            in_db=in_db->next;
        }
        break;
        case READLINE:
        if((fscanf(f," \"%[^\"]\",",in_db->title     ))<0)break;
        if((fscanf(f," \"%[^\"]\",",in_db->first_name))<0)break;
        if((fscanf(f," \"%[^\"]\",",in_db->last_name ))<0)break;
        if((fscanf(f," \"%[^\"]\",",buf              ))<0)break;
        if((fscanf(f," \"%[^\"]\" ",in_db->publ      ))<0)break;
        in_db->date=str2time (buf);
        break;
        case READ:
        while (!feof(f)) {
            dao (READLINE,f,in_db,NULL);
            TRY (rec=malloc(sizeof(db_t)));
            *rec=*in_db; /* copy contents */
            rec->next=hd;/* to linked list */
            hd=rec;i++;
        }
        if (i<2) {
            puts ("Empty database. Please create some entries.");
            fclose (f);
            exit (0);
        }
        break;
        case SORT:
        rec=in_db;
        for (;in_db;i++) in_db=in_db->next;
        TRY (pdb=malloc(i*sizeof(pdb_t)));
        in_db=rec;
        for (i=0;in_db;i++) {
            pdb[i]=in_db;
            in_db=in_db->next;
        }
        qsort (pdb,i,sizeof in_db,sortby);
        pdb[i-1]->next=NULL;
        for (;i;i--) {
//            pdb[i-1]->next=pdb[i]; //153
        }
        rec=pdb[0];
        FREE (pdb);
        pdb=NULL;
        break;
        case DESTROY: {
            while ((rec=in_db)) {
                in_db=in_db->next;
                FREE (rec);
    }   }   }
    return rec;
}
/* convert numeric time to date string */
static char *time2str (time_t *time) {
    static char buf[255];
    struct tm *ptm;
    ptm=localtime (time);
    strftime(buf, 255, "%m-%d-%Y", ptm);
    return buf;
}
/* convert date string to numeric time */
static time_t str2time (char *date) {
    struct tm tm;
    memset (&tm, 0, sizeof(struct tm));
    strptime(date, "%m-%d-%Y", &tm);
    return mktime(&tm);
}
/* sort by date callback for qsort */
/*static int by_date (pdb_t *p1, pdb_t *p2) {
    if ((*p1)->date < (*p2)->date) {
        return -1;
    }
    else return ((*p1)->date > (*p2)->date);
}
0
Loinch
13 / 6 / 2
Регистрация: 25.03.2014
Сообщений: 89
29.03.2014, 18:00  [ТС] 12
Для тех, кто ищет простую базу данных на Си в текстовом формате CSV, публикую работающую версию:
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
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
#include <stdio.h>
#include <stdlib.h> /* malloc */
#include <string.h> /* strlen */
#define _XOPEN_SOURCE /* requred for time functions */
#define __USE_XOPEN
#include <time.h>
#define DB "database.csv" /* database name */
#define TRY(a)  if (!(a)) {perror(#a);exit(1);}
#define TRY2(a) if((a)<0) {perror(#a);exit(1);}
#define FREE(a) if(a) {free(a);a=NULL;}
#define sort_by(foo) \
static int by_##foo (const void*p1, const void*p2) { \
    return strcmp ((*(const pdb_t*)p1)->foo, (*(const pdb_t*)p2)->foo); }
typedef struct db {
    char title[26];
    char first_name[26];
    char last_name[26];
    time_t date;
    char publ[100];
    struct db *next;
}
db_t,*pdb_t;
typedef int (sort)(const void*, const void*);
enum {CREATE,PRINT,TITLE,DATE,AUTH,READLINE,READ,SORT,DESTROY};
static pdb_t dao (int cmd, FILE *f, pdb_t db, sort sortby);
static char *time2str (time_t *time);
static time_t str2time (char *date);
/* qsort callbacks */
sort_by(last_name);
sort_by(title);
static int by_date(pdb_t *p1, pdb_t *p2);
/* main */
int main (int argc, char **argv) {
    char buf[100];
    const char *commands[]={"-c", "-p", "-t", "-d", "-a", NULL};
    db_t db;
    db.next=NULL;
    pdb_t dblist;
    int i;
    FILE *f;
    TRY (f=fopen(DB,"a+"));
    if (argc<2) {
usage:  printf ("Usage: %s [commands]\n"
        "-c  Create new entry.\n"
        "-p  Print the latest entry.\n"
        "-t  Print all entries sorted by title.\n"
        "-d  Print all entries sorted by date.\n"
        "-a  Print all entries sorted by author.\n",argv[0]);
        fclose (f);
        return 0;
    }
    for (i=0;commands[i]&&strcmp(argv[1],commands[i]);i++);
    switch (i) {
        case CREATE:
        printf("-c  Create a new entry.\n");
        printf("Title           :");if((scanf(" %25[^\n]",db.title     ))<0)break;
        printf("Author Firstname:");if((scanf(" %25[^\n]",db.first_name))<0)break;
        printf("Author Lastname :");if((scanf(" %25[^\n]",db.last_name ))<0)break;
        printf("Date 10-12-2000 :");if((scanf(" %10[^\n]",buf          ))<0)break;
        printf("Publication     :");if((scanf(" %99[^\n]",db.publ      ))<0)break;
        db.date=str2time (buf);
        dao (CREATE,f,&db,NULL);
        break;
        case PRINT:
        printf ("-p  Print the latest entry.\n");
        while (!feof(f)) dao (READLINE,f,&db,NULL);
        dao (PRINT,f,&db,NULL);
        break;
        case TITLE:
        printf ("-t  Print all entries sorted by title.\n");
        dblist = dao (READ,f,&db,NULL);
        dblist = dao (SORT,f,dblist,by_title);
        dao (PRINT,f,dblist,NULL);
        dao (DESTROY,f,dblist,NULL);
        break;
        case DATE:
        printf ("-d  Print all entries sorted by date.\n");
        dblist = dao (READ,f,&db,NULL);
        dblist = dao (SORT,f,dblist,(int (*)(const void *,const  void *)) by_date);
        dao (PRINT,f,dblist,NULL);
        dao (DESTROY,f,dblist,NULL);
        break;
        case AUTH:
        printf ("-a  Print all entries sorted by author.\n");
        dblist = dao (READ,f,&db,NULL);
        dblist = dao (SORT,f,dblist,by_last_name);
        dao (PRINT,f,dblist,NULL);
        dao (DESTROY,f,dblist,NULL);
        break;
        default: {
            printf ("Unknown command: %s.\n",strlen(argv[1])<10?argv[1]:"");
            goto usage;
    }   }
    fclose (f);
    return 0;
}
/* Data Access Object (DAO) */
static pdb_t dao (int cmd, FILE *f, pdb_t in_db, sort sortby) {
    pdb_t *pdb=NULL,rec=NULL,hd=NULL;
    int i=0,ret;
    char buf[100];
    switch (cmd) {
        case CREATE:
        fprintf (f,"\"%s\",",in_db->title);
        fprintf (f,"\"%s\",",in_db->first_name);
        fprintf (f,"\"%s\",",in_db->last_name);
        fprintf (f,"\"%s\",",time2str(&in_db->date));
        fprintf (f,"\"%s\" \n",in_db->publ);
        break;
        case PRINT:
        for (;in_db;i++) {
            printf ("Title       : %s\n",     in_db->title);
            printf ("Author      : %s %s\n",  in_db->first_name, in_db->last_name);
            printf ("Date        : %s\n",     time2str(&in_db->date));
            printf ("Publication : %s\n\n",   in_db->publ);
            if (!((i+1)%3)) {
                printf ("Press Enter to continue.\n");
                ret = scanf ("%*[^\n]");
                if (ret<0) return rec; /* handle EOF */
                else getchar();
            }
            in_db=in_db->next;
        }
        break;
        case READLINE:
        if((fscanf(f," \"%[^\"]\",",in_db->title     ))<0)break;
        if((fscanf(f," \"%[^\"]\",",in_db->first_name))<0)break;
        if((fscanf(f," \"%[^\"]\",",in_db->last_name ))<0)break;
        if((fscanf(f," \"%[^\"]\",",buf              ))<0)break;
        if((fscanf(f," \"%[^\"]\" ",in_db->publ      ))<0)break;
        in_db->date=str2time (buf);
        break;
        case READ:
        while (!feof(f)) {
            dao (READLINE,f,in_db,NULL);
            TRY (rec=malloc(sizeof(db_t)));
            *rec=*in_db; /* copy contents */
            rec->next=hd;/* to linked list */
            hd=rec;i++;
        }
        if (i<2) {
            puts ("Empty database. Please create some entries.");
            fclose (f);
            exit (0);
        }
        break;
        case SORT:
        rec=in_db;
        for (;in_db;i++) in_db=in_db->next;
        TRY (pdb=malloc(i*sizeof(pdb_t)));
        in_db=rec;
        for (i=0;in_db;i++) {
            pdb[i]=in_db;
            in_db=in_db->next;
        }
        qsort (pdb,i,sizeof in_db,sortby);
        pdb[i-1]->next=NULL;
        for (i=i-1;i;i--) {
            pdb[i-1]->next=pdb[i];
        }
        rec=pdb[0];
        FREE (pdb);
        pdb=NULL;
        break;
        case DESTROY: {
            while ((rec=in_db)) {
                in_db=in_db->next;
                FREE (rec);
    }   }   }
    return rec;
}
/* convert numeric time to date string */
static char *time2str (time_t *time) {
    static char buf[255];
    struct tm *ptm;
    ptm=localtime (time);
    strftime(buf, 255, "%m-%d-%Y", ptm);
    return buf;
}
/* convert date string to numeric time */
static time_t str2time (char *date) {
    struct tm tm;
    memset (&tm, 0, sizeof(struct tm));
    strptime(date, "%m-%d-%Y", &tm);
    return mktime(&tm);
}
/* sort by date callback for qsort */
static int by_date (pdb_t *p1, pdb_t *p2) {
    if ((*p1)->date < (*p2)->date) {
        return -1;
    }
    else return ((*p1)->date > (*p2)->date);
}
1
29.03.2014, 18:00
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
29.03.2014, 18:00

Неработает программа (образец)
var f:TStringList;//переменная типа TStringList S:String;//Обычная...

Нужен образец несложной БД
У кого-нибудь есть несложная БД в MS SQL на посмотреть?

Образец курсовой работы
Делаю курсовик по паскалю,первый раз в жизни с этим сталкиваюсь кто нибудь...


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

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

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