Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.68/40: Рейтинг темы: голосов - 40, средняя оценка - 4.68
8 / 8 / 10
Регистрация: 16.10.2012
Сообщений: 523

Работа с DBF файлами

05.10.2015, 14:03. Показов 7947. Ответов 8
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
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
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
/*          Hабор подпрограмм Borland C/C++  v3.1              */
/*            для обработки    файлов DBase.                   */
/* 1. DBF *OpenDBF(char *name) - открыть существующий DBF-файл */
/*    для записи и чтения. Возвращает указатель на открытый    */
/*    файл DBF или NULL,если открыть файл невозможно           */
/* 2. CloseDBF(DBF * file) - закрыть DBF-файл                  */
/* 3. GotoRecord(DBF * file,long n) - переход на запись n      */
/*                                       (сделать текущей)     */
/* 4. AskRecordStructure(DBF * file,char * buffer) - помещение */
/*     структуры DBF-файла в buffer                            */
/* 5. SaveRecord(DBF * file) - запись текущей записи в файл    */
/* 6. ReadRecord(DBF * file) - чтение текущей записи из файла  */
/* 7. GetField(DBF * file,char *field_name,char *buffer) -     */
/*     чтение поля field_name из текущей записи в buffer       */
/* 8. PutField(DBF * file,char *field_name,char *buffer) -     */
/*     запись buffer'a в поле field_name текущей записи        */
/* 9. NewRecord(DBF *file,char dup)-вставить запись за текущей */
/*               и сделать её текущей.                         */
/*     dup=0 - новая запись очищается,не 0 - дублируется старая*/
/*10. Pack(DBF *file) - УДАЛЕИЕ помеченных записей            */
/******  Смотри комментарии в текстах подпрограмм **************/
#include <io.h>
#include <fcntl.h>
#include <stdio.h>
//#include <alloc.h>
#include <malloc.h>
#include <string.h>
#include <stdlib.h>
#define EOFields 0x0D  /* Символ конца списка полей */
#define DBF struct _DBF_ /* Описатель файлов DBase : DBF [указатель] */
struct _field_definition_ /* СТРУКТУРА ПОЛЯ  */
{
    char name[11]; /* Имя поля */
    char tag;  /* Тип :'C', 'N', 'L', 'D', 'M' */
    long addr;  /* К-во байт от начала записи до начала поля */
    unsigned char width; /* Ширина поля */
    unsigned char prec; /* Точность */
    char other[14]; /* Резерв */
};
struct _header_definition_ /* Структура заголовка файла DBF */
{
    char Tag;  /* Hаличие файла примечаний (DBT):0x83 - есть,
               * 0x03 - нет */
    char LastUpdate[3]; /* Дата последнего обновления: ГМД */
    long FileSize; /* Кол-во записей в файле */
    int HeaderSize; /* Размер заголовка */
    int RecordSize; /* Длина записи */
    char other[20]; /* other[0] содеpжит после откpытия файла кол-во
                    * полей*/
    struct _field_definition_ Field[]; /* Описание полей */
};
/*  Файл DBF на диске
offset         size name   text
(byte)
0              1       Tag  аличие файла примечаний; Y=0x83: N=0x3
1              3       LastUpdate Год, месяц, дата последнего обновления
4              4       FileSize Количество записей в файле
8              2       HeaderSize Размер заголовка = 32+32*(число_полей)+2
10             2       RecordSize Длина записи с лидирующим тегом удаления
12             20      other
Feild N 1
32+0           11      name[1]  Имя поля N 1 (дополнено 0x0)
32+11          1       tag[1]  Тип поля: 'C', 'N', 'L', 'D' или 'M'
32+12          4       addr[1]  Смещение записи от начала поля
32+16          1       width[1] Ширина поля
32+17          1       prec[1]  Точность
32+18          14      other  Резерв (=0x0)
..... .. ......  ....................................
Feild N f
32*n+0         11      name[f]  Имя поля N f (дополнено 0x0)
32*n+11        1       tag[f]  Тип поля: 'C', 'N', 'L', 'D' или 'M'
32*n+12        4       addr[f]  Смещение записи от начала поля
32*n+16        1       width[f] Ширина поля
32*n+17        1       prec[f]  Точность
32*n+18        14      other  Резерв (=0x0)
 
32*(n+1)        1       '0x0D'
32*(n+1)+1      1       '0x00'
Record N 1
32*(n+1)+2+0 1 del      Тег удаления;
не помечено к удалению = 0x20,
помечено к удалению = 0x2A=='*'
32*(n+1)+2+1  width[1]  Запись N 1 поля N 1
width[2]  Запись N 1 поля N 2
........  ...................
width[f]  Запись N 1 поля N f
...........................................................
Record N r
32*(n+1)+2+RecrdSize*r+0
1 del  Тег удаления;
32*(n+1)+2+RecrdSize*r+1
width[1]  Запись N r поля N 1
width[2]  Запись N r поля N 2
........  ...................
width[f]  Запись N r поля N f
'0x1A'  Маркер конца файла
*/
 
 
struct _DBF_   /* Структура файла DBF */
{
    int MainFile; /* омер канала открытого файла */
    struct _header_definition_ * Header; /* Заголовок */
    char * Record; /* Указатель на начало текущей записи в памяти
                   Record[0]='*'- запись помечена к удалению  */
    long nrec;  /* омер текущей записи-1 */
    int ExtentionFile; /* Канал файла DBT */
    long first_free_block; /* Адрес первого свободного блока */
    char chained; /* Запись в файл: 1-разрешена, 0-запрещена */
};
 
int DBF_error;  /* номер ошибки при работе с DBF-файлами;
                если меньше 100, то совпадает с общей ошибкой */
char * DBF_error_list[] =
{
    "Invalid .DBF file header", /* 100 */
    "Invalid .DBT file header", /* 101 */
    "Begin of file",            /* 102 */
    "New record"                /* 103 */
};
 
int ReadRecord( DBF * file )
{ long pos;
pos = file->Header->HeaderSize +
    file->Header->RecordSize * file->nrec;
lseek( file->MainFile,pos,SEEK_SET );
_read( file->MainFile,file->Record,file->Header->RecordSize );
file->chained = 0;
return(0);
}
 
DBF * OpenDBF(char * name)                  /* name - можно без расширения
                                            */
{
    char temp[100];
    char hdrb[31];
    long ltemp;
    int  i;
    volatile unsigned int p;
    int  MainFile,ExtentionFile,HeaderSize,RecordSize;
    DBF  * ret;
    MainFile      = -1;
    ExtentionFile = -1;
    ret           = NULL;
    ltemp         = 0;
    DBF_error = 0;
    /* определяем имя файла данных */
    strcpy(temp,name);
    if ( strchr(temp,'.') == NULL ) strcat( temp,".DBF");
    else *strchr(name,'.')=0;
    if ( ( MainFile = _open(temp,O_RDWR) ) < 0 ) DBF_error = errno;
    if ( DBF_error == 0 )
        if ( _read(MainFile,hdrb,31)<31 )
            DBF_error = 100;
    if ( DBF_error == 0 ) {
        HeaderSize = *((int*)(hdrb+8));
        RecordSize = *((int*)(hdrb+10));
        if ( HeaderSize<32 || RecordSize<1 ||
            ( hdrb[0] != 0x03 && hdrb[0]!=0x83 ) ) DBF_error = 100;
    }
    if ( DBF_error == 0 && hdrb[0] == 0x83 ) {
        strcpy(temp,name);
        strcat(temp,".DBT");
        if ( ( ExtentionFile = _open(temp,O_RDWR) ) >= 0 )
            if ( _read(ExtentionFile,&ltemp,4)< 4 ) DBF_error = 101;
    }
    if ( DBF_error == 0 )
        if ( ( ret = (_DBF_ *)malloc(sizeof(DBF)+HeaderSize+RecordSize) ) ==
            NULL )
            //    if ( ( ret = malloc(sizeof(DBF)+HeaderSize+RecordSize) ) == NULL )
            DBF_error = errno;
    if ( DBF_error == 0 ) {
        ret -> MainFile      = MainFile;
        ret -> ExtentionFile = ExtentionFile;
        //  ret -> Header        = (void*)(((char*)ret) + sizeof(DBF));
        ret -> Header        = (_header_definition_ *)(((char*)ret) +
            sizeof(DBF));      
        ret -> Record        = ((char*)ret->Header) + HeaderSize;
        ret -> nrec          = 0;
        ret -> first_free_block = ltemp;
        lseek( MainFile,0,SEEK_SET );
        _read( MainFile,ret->Header,HeaderSize );
        /* проставляем адреса в полях */
        p = 1;
        for( i=0; (ret->Header->Field[i].name[0]) != EOFields; i++ ) {
            ret->Header->Field[i].addr = p;
            p = p + (unsigned int)((ret->Header->Field[i]).width);
        }
        ret->Header->other[0]=i;               /* Запомнили кол-во полей */
        ReadRecord( ret );
        return( ret );
    }
    else{
        if ( MainFile  >= 0 ) _close( MainFile );
        if ( ExtentionFile >= 0 ) _close( ExtentionFile );
        if ( ret !=0 ) free(ret);
        return ( NULL ); }
}
 
int SaveRecord( DBF * file )
{
    long pos;
    char EOF_record = 0x1A;
    if ( file->chained ) /* Проверка разрешения записи */
    {
        if ( file->Record[0] != '*' ) file->Record[0] = ' ';
        pos = (file->Header)->HeaderSize + (file->Header)->RecordSize *
            file->nrec;
        lseek( file->MainFile,pos,SEEK_SET );
        _write(file->MainFile,file->Record,(file->Header)->RecordSize);
        if ( file->nrec == file->Header->FileSize )
        { /* происходит расширение файла */
            file->Header->FileSize ++;
            _write(file->MainFile,&EOF_record,1);
        }
    }
    return( 0 );
}
 
int CloseDBF( DBF * file )
{
    SaveRecord(file);
    lseek( file->MainFile,0,SEEK_SET);
    _write(file->MainFile,file->Header,(file->Header)->HeaderSize);
    _close(file->MainFile);
    if ( file->ExtentionFile >= 0 ) {
        lseek( file->ExtentionFile,0,SEEK_SET );
        _write(file->ExtentionFile,&(file->first_free_block),4);
        _close(file->ExtentionFile);
    }
    free(file);
    return( 0 );
}
 
int GotoRecord( DBF * file,long rec )
{                                     /* Записывается в файл текущая  */
    DBF_error = 0;                        /*  запись,а на ее место читается */
    SaveRecord(file);                     /*   новая и делается текущей    */
    if ( rec < 1 ) { rec = 1; DBF_error = 102; }
    if ( rec > file->Header->FileSize )
    { rec = file->Header->FileSize; DBF_error = 103; }
    file->nrec = rec-1;
    ReadRecord(file);
    return( 0 );
}
 
void AskRecordStructure( DBF * file, char * buff )
{
    int i,p; p=0;
    for( i=0 ; file->Header->Field[i].name[0] != EOFields ; i++ ) {
        p += sprintf(&buff[p],"%1.*s{%c:%d:%d}",
            (int)11,file->Header->Field[i].name,
            file->Header->Field[i].tag,
            (int)file->Header->Field[i].width,
            (int)file->Header->Field[i].prec      ); }
}
 
char * GetField( DBF * file, char * field_name, char * buff ) {
    int i;
    for( i=0 ; file->Header->Field[i].name[0] != EOFields ; i++ ) {
        if ( strnicmp( file->Header->Field[i].name, field_name,11) == 0 ) {
            memcpy( buff, file->Record+file->Header->Field[i].addr,
                file->Header->Field[i].width                  );
            *(buff+file->Header->Field[i].width) = NULL;
            return( buff );
        } }
    return( NULL );
}
 
int PutField( DBF * file, char * field_name, char * buff ) {
    int i;
    for( i=0 ; file->Header->Field[i].name[0] != EOFields ; i++ ) {
        if ( strnicmp( file->Header->Field[i].name, field_name,11) == 0 ) {
            memcpy( file->Record+file->Header->Field[i].addr, buff,
                file->Header->Field[i].width);
            file->chained = 1;
            return( 0 );
        } }
    return( 1 );
}
 
int NewRecord(DBF *file,char dup) {
    int k;
    if(file->Header->FileSize < 1)  {
        file->nrec = 0; file->chained=1; SaveRecord(file);
        return(0);
    };
    k=file->nrec;
    for(file->nrec=file->Header->FileSize;file->nrec>k; ) {
        if((file->nrec==k+1)&&(dup==0))
            memset(file->Record,' ',file->Header->RecordSize);
        else {
            file->nrec--; ReadRecord(file);
            file->nrec++; };
        file->chained=1;
        SaveRecord(file);
        file->nrec--; };
    file->nrec=k+1;
}
 
int DelRecord(DBF *file) /* Удаление текущей записи */
{
    int k;
 
    if(file->nrec!=file->Header->FileSize-1)
    {
        k=file->nrec;
        for(;file->nrec<file->Header->FileSize-1; )
        {
            file->nrec++;
            ReadRecord(file);
            file->nrec--;
            file->chained=1;
            SaveRecord(file);
            file->nrec++;
        };
        file->nrec=k;
    }
    else  file->nrec--;
    file->Header->FileSize--;
    chsize(file->MainFile,
 
        file->Header->HeaderSize+(file->Header->FileSize)*(file->Header->RecordSize)
        );
}
 
int Pack(DBF *file)
{
    for(file->nrec=0;file->nrec<file->Header->FileSize;)
    {
        ReadRecord(file);
        if(file->Record[0]=='*')
        {
            DelRecord(file);
            file->nrec--;
        };
        file->nrec++;
    };
    file->nrec=0;       /* Текущей записью становится 1-ая */
}
Доброго времени суток, нашел я тут код, который вроде как по идее должен работать с DBF файлами, но возникли ряд ошибок, т.к. я в с++ только месяц, объясните в чем ошибки?
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
05.10.2015, 14:03
Ответы с готовыми решениями:

Работа с dbf
Читаю dbf файл с помощью ADO-&gt;ODBC. Есть поле номер, причем в нем либо информация либо n-пробелов. Как узнать есть ли там полезная...

Работа с dbf-файлами
Впервые работаю в php с DBF-файлами. И сразу же не идет... Подскажите,в чем может причина. Нужно ли прописивать для работы...

Работа с DBF-файлами
Выручайте, я с embracadero с++ Builder никогда не работал и тем более с форматом DBF. Как мне открыть DBF файл в режим чтения,записи и...

8
 Аватар для Mesteriis
599 / 237 / 69
Регистрация: 08.08.2015
Сообщений: 1,637
05.10.2015, 14:20
Darkvoid, А что у вас компилятор говорит, потому что я сижу на qt и соответсвенно не могу подключать ряд библиотек, а по тексту он мне только поругался что не по стандарту (std 11) написаны несколько кусков но нечего страшного!
0
3176 / 1935 / 312
Регистрация: 27.08.2010
Сообщений: 5,131
Записей в блоге: 1
05.10.2015, 15:15
Цитата Сообщение от Darkvoid Посмотреть сообщение
в чем ошибки?
Поправил пару мелочей, работоспособность не проверял.
Вложения
Тип файла: 7z test.cpp.7z (3.4 Кб, 43 просмотров)
Тип файла: 7z DBF Lib 2.0.7z (19.1 Кб, 45 просмотров)
0
3176 / 1935 / 312
Регистрация: 27.08.2010
Сообщений: 5,131
Записей в блоге: 1
05.10.2015, 15:43
Еще по теме.
Вложения
Тип файла: 7z db_c 1.06.7z (79.9 Кб, 29 просмотров)
0
8 / 8 / 10
Регистрация: 16.10.2012
Сообщений: 523
05.10.2015, 16:07  [ТС]
gazlan, а зачем мне проект DBF_Lib_2.0.7? Его нужно как-то подключить к проекту?
0
8 / 8 / 10
Регистрация: 16.10.2012
Сообщений: 523
05.10.2015, 16:20  [ТС]
gazlan, попытался запустить проект, выдает ошибку чтения по адресу
Вложения
Тип файла: rar DBReader.rar (2.55 Мб, 31 просмотров)
0
3176 / 1935 / 312
Регистрация: 27.08.2010
Сообщений: 5,131
Записей в блоге: 1
05.10.2015, 16:40
Цитата Сообщение от Darkvoid Посмотреть сообщение
зачем мне проект DBF_Lib_2.0
Только ради информации о структуре DBF-файла и списка возможных функций для работы с ним. Подключить эту библиотеку можно только при использовании TC 2.0.

Не по теме:

Не знаю целей, но найденный вами код доброго слова не стоит. Можете поискать что-либо более современное.
Например: Creation and memory mapping existing DBF files as alternative of data serialization during work with modified CListCtrl classes in virtual mode on dialogs of MDI application



Добавлено через 18 минут
Цитата Сообщение от Darkvoid Посмотреть сообщение
выдает ошибку чтения
Отладчиком не умеете пользоваться?

Кривой код. Сначала он падает на попытке модификации строкового литерала, потом на парсинге заголовка. Как минимум, нужно проследить за однобайтным выравниванием основных структур. Дальше не смотрел...
0
8 / 8 / 10
Регистрация: 16.10.2012
Сообщений: 523
05.10.2015, 17:25  [ТС]
gazlan, спасибо, просто попытка довести до ума код, не вышла)
0
3176 / 1935 / 312
Регистрация: 27.08.2010
Сообщений: 5,131
Записей в блоге: 1
05.10.2015, 17:40
Судя по характерным ошибкам, что-то времен FIDO. Нет смысла гальванизировать труп.

Если требуется только чтение существующих файлов, то проще всего сделать мэппинг DBF в память и работать с ним как с массивом записей.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
05.10.2015, 17:40
Помогаю со студенческими работами здесь

Работа с DBF-файлами
День добрый. Есть какое-то работающее решение? Ну или хотя бы какой-то консольный конвертер из DBF во что-то, что можно парсить. ...

работа с dbf файлами в Windows XP
Моё приложение работает с dbf файлами через connection_string = 'Driver={Microsoft Visual FoxPro Driver}; SourceType=DBF; SourceDB = '...

Работа с dbf в C# - вывести содержимое dbf в dataGridView
Необходимо вывести содержимое dbf в dataGridView, подскажите как сделать.... Заранее спасибо....

Помогите с dbf-файлами
Мне нужно 5 dbf-ок собрать в одну БД в делфи и потом работать с ней с помощью SQL-запросов Заранее БОЛЬШОЕ спвсибо!!!

IIS не хочет работать с dbf файлами
здравствуйте. проблема заключается в следующем: поднял IIS сервер на Windows XP, но при обращении к dbf файлам вылетает исключение. ...


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

Или воспользуйтесь поиском по форуму:
9
Ответ Создать тему
Новые блоги и статьи
Использование SDL3-callbacks вместо функции main() на Android, Desktop и WebAssembly
8Observer8 24.01.2026
Если вы откроете примеры для начинающих на официальном репозитории SDL3 в папке: examples, то вы увидите, что все примеры используют следующие четыре обязательные функции, а привычная функция main(). . .
моя боль
iceja 24.01.2026
Выложила интерполяцию кубическими сплайнами www. iceja. net REST сервисы временно не работают, только через Web. Написала за 56 рабочих часов этот сайт с нуля. При помощи perplexity. ai PRO , при. . .
Модель сукцессии микоризы
anaschu 24.01.2026
Решили писать научную статью с неким РОманом
http://iceja.net/ математические сервисы
iceja 20.01.2026
Обновила свой сайт http:/ / iceja. net/ , приделала Fast Fourier Transform экстраполяцию сигналов. Однако предсказывает далеко не каждый сигнал (см ограничения http:/ / iceja. net/ fourier/ docs ). Также. . .
http://iceja.net/ сервер решения полиномов
iceja 18.01.2026
Выкатила http:/ / iceja. net/ сервер решения полиномов (находит действительные корни полиномов методом Штурма). На сайте документация по API, но скажу прямо VPS слабенький и 200 000 полиномов. . .
Расчёт переходных процессов в цепи постоянного тока
igorrr37 16.01.2026
/ * Дана цепь(не выше 3-го порядка) постоянного тока с элементами R, L, C, k(ключ), U, E, J. Программа находит переходные токи и напряжения на элементах схемы классическим методом(1 и 2 з-ны. . .
Восстановить юзерскрипты Greasemonkey из бэкапа браузера
damix 15.01.2026
Если восстановить из бэкапа профиль Firefox после переустановки винды, то список юзерскриптов в Greasemonkey будет пустым. Но восстановить их можно так. Для этого понадобится консольная утилита. . .
Сукцессия микоризы: основная теория в виде двух уравнений.
anaschu 11.01.2026
https:/ / rutube. ru/ video/ 7a537f578d808e67a3c6fd818a44a5c4/
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru