سؤال
GCC 4.5.1 C89
أنا أستخدم الكود التالي للقراءة في سطر النص من ملف التكوين. ملف التكوين صغير في الوقت الحالي ، سوف ينمو مع حقول جديدة لإضافتها. ويمكنني تصميم ما سيبدو عليه ملف التكوين بشكل كبير. لذلك فعلت ذلك بالطريقة التالية:
config.cfg
# Configuration file to be loaded
# protocol to use either ISDN, SIP,
protocol: ISDN
# run application in the following mode, makecall or waitcall
mode: makecall
لقد استخدمت القولون كوسيلة للبحث عن نوع التكوين المطلوب. أنا فقط أتساءل عما إذا كان هناك طريقة أفضل للقيام بذلك؟
الكود الذي استخدمته هو على النحو التالي:
static int load_config(FILE *fp)
{
char line_read[LINE_SIZE] = {0};
char *type = NULL;
char field[LINE_SIZE] = {0};
char *carriage_return = NULL;
/* Read each line */
while(fgets(line_read, LINE_SIZE, fp) != NULL) {
if(line_read != NULL) {
/* Ignore any hashs and blank lines */
if((line_read[0] != '#') && (strlen(line_read) > 1)) {
/* I don't like the carriage return, so remove it. */
carriage_return = strrchr(line_read, '\n');
if(carriage_return != NULL) {
/* carriage return found so relace with a null */
*carriage_return = '\0';
}
/* Parse line_read to extract the field name i.e. protocol, mode, etc */
parse_string(field, line_read);
if(field != NULL) {
type = strchr(line_read, ':');
type+=2; /* Point to the first character after the space */
if(strcmp("protocol", field) == 0) {
/* Check the protocol type */
printf("protocol [ %s ]\n", type);
}
else if (strcmp("mode", field) == 0) {
/* Check the mode type */
printf("mode [ %s ]\n", type);
}
}
}
}
}
return TRUE;
}
/* Extract the field name for the read in line from the configuration file. */
static void parse_string(char *dest, const char *string)
{
/* Copy string up to the colon to determine configuration type */
while(*string != ':') {
*dest++ = *string++;
}
/* Insert nul terminator */
*dest = '\0';
}
المحلول
يجب أن يكون أسهل:
static int load_config(FILE *fp)
{
int r=0;
char line[LINE_SIZE], field[LINE_SIZE], type[LINE_SIZE], dummy[LINE_SIZE];
/* Read each line */
while( fgets(line, LINE_SIZE, fp) )
{
if( strchr(line,'\n') ) *strchr(line,'\n')=0;
if( 3==sscanf(line,"%[^: ]%[: ]%s,field,dummy,type) )
++r,printf("\n %s [ %s ]",field,type);
}
return r;
}
نصائح أخرى
<regex.h>
هل صديقك!
http://www.gnu.org/s/libc/manual/html_node/regular-expressions.html
إذا تمكنت من تصميم ما سيبدو ملف التكوين كما سأذهب إلى XML ، فإن تحليله المغترب. إنه غير مؤلم.
الإجابة القياسية لمشكلة التحليل البسيطة هي استخدام LEX و YACC.
ومع ذلك ، نظرًا لأن لديك حرية في تعيين شكل ملف التكوين ، يجب عليك استخدام إحدى المكتبات العديدة التي تنفذ تنسيقات ملفات التكوين المختلفة ، واستخدام ذلك فقط.
http://www.google.com/search؟q=Configuration+File+Parser
http://www.nongnu.org/confuse/ على سبيل المثال ، يبدو أنه يغطي احتياجاتك بشكل كافٍ ، لكن ألقِ نظرة على العديد من الخيارات الأخرى التي قد تكون أبسط أيضًا.