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

Чтение и сохранение данных из конфигурационного файла - C++

Восстановить пароль Регистрация
 
Рейтинг: Рейтинг темы: голосов - 19, средняя оценка - 4.79
fanatjan
0 / 0 / 0
Регистрация: 20.09.2011
Сообщений: 51
27.09.2011, 21:33     Чтение и сохранение данных из конфигурационного файла #1
Привет всем!!
Есть программа на C с конфигурационным файлом!!! Надо сделать так чтобы при старте программы конфиг файл читался один раз, в дальнейшем вторичного чтения не должно произойти!!! Данные из конфиг файла должны сохраниться в функциях и в дальнейшем использоваться!!!!
как лучше всего это сделать?, где лучше всего сохранить переменные(с данными из config файла)?, и как избежать повторного чтения config файла?
Подскажите направление, куда нужно копать?
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
27.09.2011, 21:33     Чтение и сохранение данных из конфигурационного файла
Посмотрите здесь:

C++ чтение данных с файла.
чтение данных из файла C++
Сохранение и чтение объекта класса в файл/из файла C++
C++ Чтение и сохранение JPEG файла
C++ Работа со структурой данных, чтение/сохранение во внешний файл
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Gepar
 Аватар для Gepar
1173 / 529 / 20
Регистрация: 01.07.2009
Сообщений: 3,512
27.09.2011, 22:27     Чтение и сохранение данных из конфигурационного файла #2
Цитата Сообщение от fanatjan Посмотреть сообщение
и как избежать повторного чтения config файла
Закрыть его после считывания.

Цитата Сообщение от fanatjan Посмотреть сообщение
где лучше всего сохранить переменные(с данными из config файла)
Ну если их немного и они нужны всем функциям то логично будет держать глобальные переменные.
kravam
быдлокодер
 Аватар для kravam
1512 / 872 / 44
Регистрация: 04.06.2008
Сообщений: 5,271
27.09.2011, 23:16     Чтение и сохранение данных из конфигурационного файла #3
Странно. Ты считай из файла столько раз, сколько тебе надо и всё, больше не считывай. Всего и делов-то. И, да, закрой его после считывания, конечно.
alkagolik
 Аватар для alkagolik
1510 / 616 / 79
Регистрация: 15.07.2011
Сообщений: 3,552
27.09.2011, 23:29     Чтение и сохранение данных из конфигурационного файла #4
Цитата Сообщение от fanatjan Посмотреть сообщение
где лучше всего сохранить переменные(с данными из config файла)?
можно специальную структуру для этого создать

Цитата Сообщение от fanatjan Посмотреть сообщение
и как избежать повторного чтения config файла?
считываний будет ровно столько, сколько это прямо указано в программе, трудно написать одно обращение и убить поток?
!! !!! !!! !!!! ... закономерность я уловил хорошо что ваш пост уместился в 4 не вопросительных предложения. вы так не кричите, кричащих не слушают. может покажете сорц?
xAtom
 Аватар для xAtom
910 / 735 / 60
Регистрация: 09.12.2010
Сообщений: 1,346
Записей в блоге: 1
28.09.2011, 01:40     Чтение и сохранение данных из конфигурационного файла #5
fanatjan, вот написал код, работа с ini-файлом и как всегда если бесплатно то не отвечаю за ошибки, писал на коленке.
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
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <memory.h>
#include <malloc.h>
#include <time.h>   
#define  BUF_KEY  32          // размер буфера для ключа
#define  BUF_VAL  255         // размер буфера для значения
#define  MAX_INI_RECORDS  7   // кол-во записей в ini-файле
 
typedef  struct _value {
  char key[BUF_KEY];
  char val[BUF_VAL];
} xvalue;
 
char*  xget_value(xvalue*  vals, const char* key);
int    xset_value(xvalue* vals, const char* key, const char* val);
int    xopen_ini(const char* filename, xvalue* arr);
int    xsave_ini(const char* filename, xvalue* arr);
 
xvalue* vals = NULL;
int   main(void) {
    int i;
    char*  file_ini  = "D:\\config.ini"; // путь к файлу
    time_t gt = time(NULL);
    struct tm*  gtm = localtime(&gt);
 
    vals = (xvalue*) malloc(sizeof(xvalue) * MAX_INI_RECORDS);
    if(vals == NULL)
           exit(1);
 
    // если ini-файл будет открыт, массив заполниться записиями из файла
    if(! xopen_ini(file_ini, vals)) { 
           free(vals);
           exit(2);
    }
    // далее в массиве содержаться значения всех записей ini-файла
 
    // вывод всех пар ключ = значение
    for(i = 0; i < MAX_INI_RECORDS; i++)
           printf("%s = %s\n", vals[i].key, vals[i].val );
    
    // вот так можно конвертировать числовое значение для не целых чисел atof
    printf("\n\tvalue: %d\n", atoi( xget_value(vals, "param1") ));
    // получение по ключу
    printf("\tvalue: %s\n", xget_value(vals, "platforms") );
 
    // изменить значение по заданному ключу
    xset_value(vals, "platforms", "Unix, Linux, OS/360");
   xset_value(vals, "video", "1");
   xset_value(vals, "date", asctime(gtm) ); 
    
   // сохранить в файл
   if(! xsave_ini(file_ini, vals))
         puts("Error, not save  ini-file!!!");
   free(vals);
   vals = NULL;
   system("pause");
   return 0;
}
 
// получения значения по указанному ключу с учётом регистра
char*  xget_value(xvalue*  vals, const char* key) {
    int i;
   for(i = 0; i < MAX_INI_RECORDS; i++) {
         if(! strcmp(vals[i].key, key))
               return vals[i].val;
   }
   return NULL;
}
 
// присваивание  нового значения по указанному ключу с учётом регистра
int  xset_value(xvalue* vals, const char* key, const char* val) {
    int i;
    for(i = 0; i < MAX_INI_RECORDS; i++) {
           if(! strcmp(vals[i].key, key)) {
                 strcpy(vals[i].val, val);
                 return 1;
           }
    }
    return 0;
}
 
// открытие файла - ini
int  xopen_ini(const char* filename, xvalue* arr) {
    xvalue val;
    FILE*  fp;
    int    cnt;
    if(! (fp = fopen(filename, "r")))
            return 0;
    memset((void*)&val, 0, sizeof(xvalue));
 
    for(cnt = 0; fscanf(fp, "%[^=]=%[^\n]%*1c", val.key, val.val) > 1; cnt++) 
             memcpy((void*)&arr[cnt], (const void*)&val, sizeof(xvalue)); 
    fclose(fp);
    return 1;
}
 
// сохранения массива записей в файл-ini
int  xsave_ini(const char* filename, xvalue* arr) {
    FILE* fp;
    int i;
    if(! (fp = fopen(filename, "w+")))
           return 0;
    rewind(fp);
    for(i = 0; i < MAX_INI_RECORDS; i++) {
           fprintf(fp, "%s=%s", arr[i].key, arr[i].val);
           if(i + 1 != MAX_INI_RECORDS)
                fputc('\n', fp);
    }
    fflush(fp);
    fclose(fp);
    return 1;
}
Формат INI-файла.
platforms=MS-DOS, Window 95
video=1
count=100
param1=200
param2=500
param3=7000
date=xxxxx
alkagolik
 Аватар для alkagolik
1510 / 616 / 79
Регистрация: 15.07.2011
Сообщений: 3,552
28.09.2011, 01:51     Чтение и сохранение данных из конфигурационного файла #6
xAtom, если не затрудняет расскажите пожалуйста?
C
1
"%[^=]=%[^\n]%*1c"
fanatjan
0 / 0 / 0
Регистрация: 20.09.2011
Сообщений: 51
28.09.2011, 11:32  [ТС]     Чтение и сохранение данных из конфигурационного файла #7
Моя программа разделена на несколько файлов!!!!!!
Например ConfigReader.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
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
#include <stdio.h>
#include <time.h>
#include <stdlib.h>
#include <string.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <stdlib.h>
#include <sys/time.h>
#include <unistd.h>
#include <ctype.h>
/////////Config File Directory
char const* FCFG="./Config/Config.txt";
////////////////
///////Directory of log//////////
char const* findDef="Path=";
///////////Level of Log
char const* findLev="Level=";
///////////////Mail
char const* findMailto="Mailto=";
////////////Trace On/Off
char const* findTrace="Trace=";
//////////////Defoult Directory of log and Trace file
const char* ErDef="ACS.log";
const unsigned MAXLINE=9999;
char  *skip_wsL(char *line)
{
    return line+strspn(line," \t");
}
char *findvalL(char *line,char const* prefix,int prelen)
{
    char *p;
    p=skip_wsL(line);
    if (strncmp(p,prefix,prelen)==0)
        return p+prelen;
    else
        return NULL;
}
int valcounter(char *text, int separ)
{
    int i=0;
    int count=0;
    while(text[i++]!= '\0')
            {
                if(text[i-1] == separ)count++;
            }
    return count;
}
 
char *findval_slowL(char *line,char const* prefix)
{
    return findvalL(line,prefix,strlen(prefix));
}
 
 
///////////////////////////Directory
void Serch(char Def[], char Num[], char Mailto[], char Trace[])
{
    FILE *fcfg;
    //////////TIME
    char *p, line[MAXLINE];
    int findDefSize, findLevSize, findMailtoSize, findTraceSize;
    ////////////
    findDefSize=strlen(findDef);
    findLevSize=strlen(findLev);
    findMailtoSize=strlen(findMailto);
    findTraceSize=strlen(findTrace);
    fcfg=fopen(FCFG,"r");
    while (p=fgets(line,MAXLINE,fcfg)) {
        ///////////////Find Directory
        if (p=findvalL(line,findDef,findDefSize)) {
            char *pend=p+strlen(p)-1;
            if (*pend=='\n') *pend=0;
            strcpy(Def,p);
 
        }
        ///////////////Find Level
        if (p=findvalL(line,findLev,findLevSize)) {
                                 char *pend=p+strlen(p)-1;
                                 if (*pend=='\n') *pend=0;
                                    strcpy(Num,p);
        }
        ///////////////Find Mail
        if (p=findvalL(line,findMailto,findMailtoSize)) {
        char *pend=p+strlen(p)-1;
        if (*pend=='\n') *pend=0;
        strcpy(Mailto,p);
        }
 
        ///////////////Find Trace 
    if (p=findvalL(line,findTrace,findTraceSize)) {
            char *pend=p+strlen(p)-1;
             if (*pend=='\n') *pend=0;
             strcpy(Trace,p);
                }
 
        }
}
////////////Delete "\0"
char * remove_spaces(char * str){
 
        char * pChar, * pTail;
        pChar= (char *)malloc(1 * sizeof(char));
        pTail= (char *)malloc(1 * sizeof(char));
        if ( ! str )
                return NULL;
 
        for ( pTail = str; *pTail; ++pTail )
                ;
 
        pChar = str;
        while ( *pChar ){
                if ( isspace(*pChar) ){
                        memmove(pChar, pChar + 1, pTail - pChar);
                        --pTail;
                }
                else
                        ++pChar;
        }
 
        return str;
}
//////////////Create correct form
void Correct(char Def[], int *Level, char Mailto[])
    {
    FILE *fileLog, *fileLogEr;
            struct timeval tv;
            struct tm* ptm;
            char time_string[40];
            long milliseconds;
            int result;
            gettimeofday (&tv, NULL);
            ptm = localtime (&tv.tv_sec);
            strftime (time_string, sizeof (time_string), "%Y-%m-%d %H:%M:%S", ptm);
            milliseconds = tv.tv_usec / 1000;
////////////////////Directory correct
        char Num[100], MTrace[100];
        Serch(Def, Num, Mailto, MTrace);
        int p, Lev;
        p=sizeof(Def);
        int i;
        remove_spaces(Def);
        for (i=0; i<p; i++)
        {
            char* ptr;
            char symbol1='\\';
            char symbol1Corr='/';
            ptr=strchr(Def,symbol1);
            if ((ptr++)!=NULL) *ptr=symbol1Corr;
 
        }
        fileLog=fopen(Def, "a");
                        if(!fileLog){
                        perror("file open error\n");
                        strcpy(Def, "Log.log");
                        fileLogEr=fopen(Def, "a");
 
                        fprintf(fileLogEr, "%s.%03ld\t|Error:%s\n", time_string, milliseconds, "Log Definition Incorect");
                        result=pclose(fileLogEr);
                        }
//////////////////Level correct
                remove_spaces(Num);
                char *CNum=Num;
                sscanf(CNum,"%d",&Lev);
                if(Lev>4)
                {
                    Lev=1;
                    fileLogEr=fopen(Def, "a");
 
                                            fprintf(fileLogEr, "%s.%03ld\t|Error:%s\n", time_string, milliseconds, "Log Level Incorect");
                                            result=pclose(fileLogEr);
                }
                *Level=Lev;
//////////////////Mail Correct
                remove_spaces(Mailto);
                int pstr;
                             pstr=strlen(Mailto);
                             if(pstr==0){
                                 fileLog=fopen(Def, "a");
                                            if(!fileLog){
                                            exit(1);
                                            }
                                        fprintf(fileLog,"%s.%03ld\t|Error:%s\n", time_string, milliseconds, "Mail List iz Empty");
                                        result=pclose(fileLog);
                                        memset(Mailto, '\0', sizeof(Mailto));
                             }
}
////////////Trace Directory
void TraceDef(char Def[], int *Trace)
{
    char MTrace[20];
    char Num[500];
    char Mailto[500];
    Serch(Def,Num, Mailto, MTrace);
    int p, Tra;
    p=strlen(Def);
    int k=0, i;
     ///////////////////////////////////////
                    remove_spaces(MTrace);
                    char *CTrace=MTrace;
                    sscanf(CTrace,"%d", &Tra);
                    *Trace=Tra;
     //////////////////////////
    for(i=0; i<p; i++)
    {
            if(Def[i]=='/')
        {
            k=i++;
        }
 
    }
    int j;
    for(j=k; j<p; j++)
    {
        Def[j]='\0';
    }
    strcat(Def, "/ACS");
 
}
///////////Send Mail function
int Send(char *EmailId){
    char message[24]={0x0};
    char cmd[128]={0x0};
    strcpy(message,"Fatal Error");
    sprintf(cmd, "echo \"%s.\" | sendmail %s ",message,EmailId);
 
    system(cmd);
    //printf("Sending\n");
    return 0;
}
//////////get mail
int Token(char Str[] )
{
    char *Token;
 
 //printf("String: %s\n", Str);
 
 Token = strtok (Str, ",!;");
 
 while (Token != NULL) {
    // printf ("%s\n", Token);
     Send(Token);
   Token = strtok (NULL, ",!;");
 }
 return 0;
}
 
[size="1"][color="grey"][I]Добавлено через 3 минуты[/I][/color][/size]
Все эти функции потом вызываются в Log.c а сам потом вызывается в main.c!!!
 
[size="1"][color="grey"][I]Добавлено через 2 минуты[/I][/color][/size]
Как сделать , чтобы конфиг файл второй раз не считывался?
У меня не сохраняются переменные в Log.c
#include <stdio.h>
#include <time.h>
#include <stdlib.h>
#include <string.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <stdlib.h>
#include <sys/time.h>
#include "include/ConfigReader.h"
//////////Thrace function
void Log(int LevelLog, const char* pFileName,const char* pFuncName, int pLine, const char errorMsg[])
{
    FILE *fileLog;
    char Def[500];
    char Mailto[500];
    /*Read config*/
        Correct(Def, &Level,  Mailto);
    /*Time struct. */
    struct timeval tv;
    struct tm* ptm;
    char time_string[40];
    long milliseconds;
    gettimeofday (&tv, NULL);
    ptm = localtime (&tv.tv_sec);
    strftime (time_string, sizeof (time_string), "%Y-%m-%d %H:%M:%S", ptm);
    /* Time milliseconds*/
//printf("Def:\n", Def);
    milliseconds = tv.tv_usec / 1000;
    ///////////if Level is 4(Fatal) send mail;
        if(LevelLog==4)
        {
            Token(Mailto);
        }
///////////////Log level
        if(LevelLog>=Level){
            fileLog=fopen(Def, "a");
            if(!fileLog){
            printf("ERROR\n");
            exit(1);
            }
        fprintf(fileLog, "%s.%03ld|Level:%d|File:%s|Func:%sLine:%i|Error:%s\n", time_string, milliseconds, LevelLog, pFileName,pFuncName,pLine, errorMsg);
        fclose(fileLog);
        }
}
//////////Thrace function
void Trace(const char Msg[])
{
    FILE *fileTrace;
    char Def[500], time_string[40];
    int TraceLev;
    TraceDef(Def,  &TraceLev);
    strcat(Def, ".trace");
    struct timeval tv;
    struct tm* ptm;
    long milliseconds;
    gettimeofday (&tv, NULL);
    ptm = localtime (&tv.tv_sec);
    strftime (time_string, sizeof (time_string), "%Y-%m-%d %H:%M:%S", ptm);
    milliseconds = tv.tv_usec / 1000;
/////////////////If Trace is ON;
      if(TraceLev==1){
          fileTrace=fopen(Def, "a");
            if(!fileTrace){
            exit(1);
        }
        fprintf(fileTrace, "%s.%03ld\t|Msg:%s\n",time_string, milliseconds, Msg);
            fclose(fileTrace);
        }
}
 Комментарий модератора 
Используйте теги форматирования кода!
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
29.09.2011, 05:22     Чтение и сохранение данных из конфигурационного файла
Еще ссылки по теме:

C++ Чтение данных из файла
Чтение данных из файла С++ C++
C++ Сохранение и чтение структуры из файла (crash программы)

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

Или воспользуйтесь поиском по форуму:
accept
4838 / 3237 / 165
Регистрация: 10.12.2008
Сообщений: 10,682
29.09.2011, 05:22     Чтение и сохранение данных из конфигурационного файла #8
кстати, %*1c == %*c
Цитата Сообщение от alkagolik
xAtom, если не затрудняет расскажите пожалуйста?
можешь сам прочитать в стандарте, в манах (там включают также стандартное описание) либо в книгах по C
ссылка
Yandex
Объявления
29.09.2011, 05:22     Чтение и сохранение данных из конфигурационного файла
Ответ Создать тему
Опции темы

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