무슨 일로 C 하셨습니까?

[C] 파일 입출력::config 파일 만들기 본문

C - 이걸 굳이?/유틸리티

[C] 파일 입출력::config 파일 만들기

OJJJ 2021. 5. 16. 21:06

앞서 만든 파일 입출력 함수를 가지고

 

나만의 config 파일을 만들어보겠다.

 


일단 설정 값들을 가질 구조체를 만든다

typedef struct _Config {
	int num;
	char* ip;
}Config;

설정 값들이 뭐가 들어갈지는 마음껏 넣어주면 되겠다.

 

더보기

좀더 동적으로 활용하고 싶다면 

2020.10.13 - [C -이걸 굳이?/유틸리티] - [C] 자료구조::딕셔너리 (Dictionary)

 

지난번에 만든 딕셔너리를 설정 값으로 넣어주면

 

설정 데이터를 동적으로 지정할 수 있을 것이다.


config 구조체에 파일로 저장된 데이터들을 읽는 함수를 만들어보자

int Config_Read(Config* config, char* path) {

	FILE* stream = NULL;
	errno_t num = fopen_s(&stream, path, "r");

	Config temp;

	// 파일이 정상적으로 열리지 않은 경우
	if (num != 0) {
		return 0;
	}

	char* value = FileRead(stream, "num");
	if(value != NULL) sscanf(value, "%d", &temp.num);

	value = FileRead(stream, "ip");
	if (value != NULL) temp.ip = StringCopy(value);

	fclose(stream);

	*config = temp;
	return 1;
}

저번에 만든 FileRead() 함수에서 value를 추출한 후 반환하도록하고

 

파라미터로 파일 경로를 주는게 아니 열린 파일의 FD를 넘겨주는 식으로 수정했다.

 

그런데 혹시라도 경로상에 config 파일이 존재하지 않는 경우가 있을 수 있으므로

void Config_WriteInit(char* path) {
	printf("init file create <%s>\n", path);


	FILE* stream = NULL;
	errno_t num = fopen_s(&stream, path, "w");

	fprintf(stream, "%s\n", "#this is example");
	fprintf(stream, "%s%d\n", "num:", 0);
	fprintf(stream, "\n%s\n", "#ip example");
	fprintf(stream, "%s%s\n", "ip:", "127.0.0.1");


	fclose(stream);
	
}

기본 config 파일을 생성해주도록 코드를 만들어 놓으면 되겠다.

 

	// 파일이 정상적으로 열리지 않은 경우
	if (num != 0) {
		Config_WriteInit(path);
		return 0;
	}

Config_Read()함수에서 파일을 읽지 못하는 경우 이렇게 수정하면 된다.

 

void main() {
    Config val;
    Config_Read(&val, "config");

    printf("vlaue is ======\n");
    printf("num : %d\n",val.num);
    printf("ip  : %s\n",val.ip);

    system("pause");
    return 909;
}

잘 동작하는지 테스트 해보자


 

#include <stdio.h>
#include <stdlib.h>
#include "StringFunc.h"

char* GetValue(char* source, char* key) {
	char** ptr = StringParser(source, ":");
	if (StringCompare(ptr[0], key) == COMPARE_SAME) {
		return ptr[1];
	}
	return NULL;
}

char* FileRead(FILE* stream, char* key) {

	char data[100];

	int num;
	char* value = NULL;

	while (fgets(data, 100, stream)) {
		if (data[0] == '#') continue;
		value = GetValue(data,key);

		if (value == NULL) continue;

		printf("value is :[%s]%s\n", key, value);
		break;
	}

	return value;
}

void Config_WriteInit(char* path) {
	printf("init file create <%s>\n", path);


	FILE* stream = NULL;
	errno_t num = fopen_s(&stream, path, "w");

	fprintf(stream, "%s\n", "#this is example");
	fprintf(stream, "%s%d\n", "num:", 0);
	fprintf(stream, "\n%s\n", "#ip example");
	fprintf(stream, "%s%s\n", "ip:", "127.0.0.1");


	fclose(stream);
	
}

int Config_Read(Config* config, char* path) {

	FILE* stream = NULL;
	errno_t num = fopen_s(&stream, path, "r");

	Config temp;

	// 파일이 정상적으로 열리지 않은 경우
	if (num != 0) {
		Config_WriteInit(path);
		return 0;
	}

	char* value = FileRead(stream, "num");
	if(value != NULL) sscanf(value, "%d", &temp.num);

	value = FileRead(stream, "ip");
	if (value != NULL) temp.ip = StringCopy(value);

	fclose(stream);

	*config = temp;
	return 1;
}

사실 C로 이거 하려니까 매우 비효율적인걸 느낀다.

 

괜히 시도한 기분이다. 만드는거 비추천이다.

'C - 이걸 굳이? > 유틸리티' 카테고리의 다른 글

[C] 파일 입출력  (0) 2021.05.12
[C] 키보드 이벤트  (0) 2021.01.25
[C] 문자열 다루기::문자열 복사  (0) 2021.01.22
[C] 메모리 반환  (0) 2020.10.15
[C] 자료구조::딕셔너리 (Dictionary) _ 2  (2) 2020.10.15
Comments