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);
}
-3
A
답변
1
- \ 복사 할 수있는 방법.
는 strstr()
에서 사용하기 전에 코드
당신은 항상 반환 값을 확인해야합니다 여러 간단하고 분명한 개선이 있습니다.
strlen("SERVERPORT = ")
은 비효율적 인 12를 작성하는 매우 추악한 방법입니다.코드를 읽기 쉽게하려면 공백을 조금 더 사용해야합니다.
- 은 단지 그것을 더 어려운 읽고 당신이 stdlib.h을 포함하는 것을 잊지 경우 버그를 숨길 수 있습니다
malloc()
의 반환 값을 캐스팅하지 마십시오. 포인터를 역 참조하기 전에
malloc()
이NULL
을 반환했는지 항상 확인하십시오.각 줄을
=
으로 분할하고 결과 값에서 주위의 모든 공백을 제거한 다음 해당 변수를 확인하고 해당 값을 할당하십시오.예를 들어
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);
}
}
설정 파일에서 특정 값을 찾기 위해 조회 기능을 추가 할 수 있습니다. 또한 여러 프로젝트에서 사용할 수있는 독립 실행 형 라이브러리로 만들 수 있습니다.
코드를 포맷하십시오. –
이 함수는 내가 알고있는'\ n' 문자를 건너 뛸 수 없습니다. 그냥 루프로 만드십시오. 어쩌면 내가 질문을하지 않았을지라도 –
줄 바꿈까지 읽는'fgets'을 사용할 수 있습니다. 줄 바꿈을 건너 뛰려면 len-1 바이트를 복사하십시오. 아니면'fscanf ("% s \ n")' –