2016-12-01 4 views
-3
struct configurations *read_file(char * file_name) 
{ 
    FILE *f = fopen(file_name ,"r"); 
    if(!f) 
    { 
     printf("**********Unable to open config.txt*********"); 
     return NULL; 
    } 

    int i, prev, count; 
    char *line = NULL, buff[480] = {'\0'}; 
    size_t len; 

    struct configurations *config = (struct configurations *) malloc(sizeof(struct configurations)); 

    while (getline(&line,&len,f) != -1) 
    { 
     if(!strncmp("SERVERPORT = ",line,strlen("SERVERPORT = "))){ 
      config->server_Port = atoi(strstr(line, " = ")+3); 
     } 
     else if(!strncmp("SCHEDULING = ",line,strlen("SCHEDULING = "))){ 
      strcpy(config->sched,strstr(line, " = ") + 3); 


     } 
+0

코드를 포맷하십시오. –

+0

이 함수는 내가 알고있는'\ n' 문자를 건너 뛸 수 없습니다. 그냥 루프로 만드십시오. 어쩌면 내가 질문을하지 않았을지라도 –

+0

줄 바꿈까지 읽는'fgets'을 사용할 수 있습니다. 줄 바꿈을 건너 뛰려면 len-1 바이트를 복사하십시오. 아니면'fscanf ("% s \ n")' –

답변

1
  • \ 복사 할 수있는 방법.

strstr()에서 사용하기 전에 코드

  1. 당신은 항상 반환 값을 확인해야합니다 여러 간단하고 분명한 개선이 있습니다.

  2. strlen("SERVERPORT = ")은 비효율적 인 12를 작성하는 매우 추악한 방법입니다.

  3. 코드를 읽기 쉽게하려면 공백을 조금 더 사용해야합니다.

  4. 은 단지 그것을 더 어려운 읽고 당신이 stdlib.h을 포함하는 것을 잊지 경우 버그를 숨길 수 있습니다 malloc()의 반환 값을 캐스팅하지 마십시오.

  5. 포인터를 역 참조하기 전에 malloc()NULL을 반환했는지 항상 확인하십시오.

  6. 각 줄을 =으로 분할하고 결과 값에서 주위의 모든 공백을 제거한 다음 해당 변수를 확인하고 해당 값을 할당하십시오.

    예를 들어 SERVERPORT=1234 인 경우 코드가 실패하고 = 연산자를 사용하는 것이 좋지 않더라도 공백을 명시 적으로 지정하지 않으면 두 코드 모두 유효해야합니다.

    또한 주변 공백을 제거하면 getline()으로 읽은 '\n'이 값에서 제거됩니다.

이 빠른 API a는 내가 모든 사람이 자신의 취향과 일을 할 수있는 방법이 있습니다 물론, 그것을 할 것입니다 방법을 보여주기 위해 지금 막 썼다, 그러나 나는 당신의 실수를 알아내는 데 도움이 희망

#include <stdio.h> 
#include <stdlib.h> 
#include <ctype.h> 
#include <string.h> 

struct KeyValue { 
    char *key; 
    char *value; 
}; 

struct KeyFile { 
    size_t size; 
    struct KeyValue *entries; 
    size_t count; 
}; 

static struct KeyFile * 
keyfile_new(void) 
{ 
    struct KeyFile *kf; 

    kf = malloc(sizeof(*kf)); 
    if (kf == NULL) 
     return NULL; 
    kf->entries = malloc(10 * sizeof(*kf->entries)); 
    if (kf->entries == NULL) { 
     kf->size = 0; 
    } else { 
     kf->size = 10; 
    } 
    kf->count = 0; 
    return kf; 
} 

static int 
keyfile_add_value(struct KeyFile *kf, const char *const key, const char *const value) 
{ 
    struct KeyValue *entry; 
    if (kf->count + 1 >= kf->size) { 
     void *pointer; 
     pointer = realloc(kf->entries, (kf->size + 10) * sizeof(*kf->entries)); 
     if (pointer == NULL) 
      return -1; 
     kf->entries = pointer; 
     kf->size += 10; 
    } 
    entry = &kf->entries[kf->count++]; 

    entry->key = strdup(key); 
    entry->value = strdup(value); 

    return 0; 
} 

static void 
keyfile_free(struct KeyFile *kf) 
{ 
    for (size_t i = 0 ; i < kf->count ; ++i) { 
     struct KeyValue *entry; 

     entry = &kf->entries[i]; 

     free(entry->key); 
     free(entry->value); 
    } 
    free(kf->entries); 
    free(kf); 
} 

static struct KeyFile * 
keyfile_read(const char *const path) 
{ 
    FILE *file; 
    struct KeyFile *kf; 
    size_t length; 
    char *line; 

    line = NULL; 
    length = 0; 
    file = fopen(path, "r"); 
    if (file == NULL) 
     return NULL; 
    kf = keyfile_new(); 
    if (kf == NULL) 
     return NULL; 
    while (getline(&line, &length, file) > 0) { 
     char *op; 
     char *key; 
     char *value; 
     op = strchr(line, '='); 
     if (op == NULL) { 
      fprintf(stderr, "malformed line!\n"); 
     } else { 
      *op = '\0'; 
      key = line; 
      while (isspace((unsigned char) *key) != 0) 
       ++key; 
      value = op + 1; 

      op -= 1; 
      while (isspace((unsigned char) *op) != 0) 
       *(op--) = '\0'; 
      while (isspace((unsigned char) *value) != 0) 
       value += 1; 
      op = value + strlen(value) - 1; 
      while (isspace((unsigned char) *op) != 0) 
       *(op--) = '\0'; 
      if (keyfile_add_value(kf, key, value) != 0) 
       goto error; 
     } 
    } 
    fclose(file); 
    free(line); 

    return kf; 
error: 
    keyfile_free(kf); 

    fclose(file); 
    free(line);  

    return NULL; 
} 

static void 
keyfile_display(const struct KeyFile *const kf) 
{ 
    for (size_t i = 0 ; i < kf->count ; ++i) { 
     const struct KeyValue *entry; 

     entry = &kf->entries[i]; 
     fprintf(stdout, "/%s/ => /%s/\n", entry->key, entry->value); 
    } 
} 

설정 파일에서 특정 값을 찾기 위해 조회 기능을 추가 할 수 있습니다. 또한 여러 프로젝트에서 사용할 수있는 독립 실행 형 라이브러리로 만들 수 있습니다.