급하게 필요해서 c 언어로 된 ini 읽는 모듈을 작성했다.
포함 된 내용은 아래와 같다.
- trim 함수 사용 (http://newtype.pe.kr/361)
- windows api의 ini 읽는 함수 원형을 흉내 냈다.(MSDN)
사용 설명
#include "../inc/ini.h"
#define MAX_LENGTH 256
int GetKeyCount(FILE *fp, char *app);
int seekApp(FILE *fp, char *app);
void getNextKey(FILE *fp, char *retKey, int sizeKey, char *retValue, int sizeValue);
int isBlank(char ch);
char* trim( char *s );
// 현재 fp 부터 검색한다.
// app 위치로 이동한다.
int seekApp(FILE *fp, char *app)
{
char str[MAX_LENGTH] ="";
char buf[MAX_LENGTH] ="";
int bingo;
// 파라이터 오류
if(strlen(app) < 1) return -1;
// 파일 핸들 오류
if(fp == 0) return -2;
sprintf(str, "[%s]", app);
// find app
bingo=0;
while( feof(fp) == 0 )
{
fgets(buf, MAX_LENGTH, fp);
if (buf[0] == 0 || buf[0] == '#') continue;
trim(buf);
if (strncmp(buf, str, strlen(str)) == 0)
{
bingo=1;
break;
}
}
// app 없음
if (bingo==0) return -3;
return 0;
}
// 현재 fp 부터 검색한다.
// 다음 key 값을 얻는다.
void getNextKey(FILE *fp, char *retKey, int sizeKey, char *retValue, int sizeValue)
{
char str[MAX_LENGTH] ="";
char buf[MAX_LENGTH] ="";
char *p=0;
int bingo;
// 파라이터 오류
if( retKey==0 || retValue==0 ) return;
// 파일 핸들 오류
if(fp == 0) return;
// find key
bingo=0;
while( feof(fp) == 0 )
{
fgets(buf, MAX_LENGTH, fp);
trim(buf);
if (buf[0] == 0 || buf[0] == '#') continue;
if (buf[0] == '[' ) return;
break;
}
// 토큰을 찾는다.
p = buf;
while( (*p != '\n') && (*p != '=') && (*p) ) p++;
// value가 있다.
if ( *p == '=' ) bingo = 1;
*p = 0;
// key!!
strncpy(retKey, trim(buf), sizeKey);
retKey[sizeKey-1] = 0;
// value
retValue[0] = 0;
if (bingo == 1)
{
strcpy(str, p+1);
// 토큰을 찾는다.
p = str;
while( (*p != '\n') && (*p) ) p++;
*p = 0;
// value!!
strncpy( retValue, trim(str), sizeValue);
retValue[sizeValue-1] = 0;
}
return;
}
// fp파일에서 [PROC] app를 찾아 key 갯수를 센다.
int GetKeyCount(FILE *fp, char *app)
{
char buf[MAX_LENGTH] ="";
int count=0;
// 파일 핸들 오류
if(fp == 0) return -2;
// 파일의 맨처음으로 이동
fseek(fp, 0L, SEEK_SET);
if ( seekApp(fp, app) != 0 ) return -3;
// count key
count=0;
while( feof(fp) == 0 )
{
fgets(buf, MAX_LENGTH, fp);
trim(buf);
if (buf[0] == '[') break;
if (buf[0] == 0 || buf[0] == '#') continue;
count++;
}
return count;
}
// fp 파일에서 app 카테고리의 key 값을 읽는다.
// ret는 들어갈 값 문자열
// size는 값문자열의 최대 길이
// return : -1 파라미터 에러
// -2 파일 핸들 에러
// -3 app 검색 실패
// -4 key 검색 실패
// 0 성공
int GetProfileString(FILE *fp, char *app, char *key, char *ret, int size)
{
char bufKey[MAX_LENGTH] ="";
char bufValue[MAX_LENGTH] ="";
char *p=0;
int bingo;
// 파라이터 오류
if( (strlen(key) < 1) || ret==0 ) return -1;
// 파일 핸들 오류
if(fp == 0) return -2;
// 파일의 맨처음으로 이동
fseek(fp, 0L, SEEK_SET);
if ( seekApp(fp, app) != 0 ) return -3;
// find key
getNextKey(fp, bufKey, sizeof(bufKey), bufValue, sizeof(bufValue) );
bingo=0;
while( bufKey[0] )
{
if ( strcmp(bufKey, key) == 0 )
{
strncpy( ret, bufValue, size );
ret[size-1]=0;
bingo=1;
break;
}
getNextKey(fp, bufKey, sizeof(bufKey), bufValue, sizeof(bufValue) );
}
// key 없음
if (bingo==0) return -4;
return 0;
}
// fp 파일에서 app 카테고리의 key 값을 읽는다.
// ret는 들어갈 int형 주소
// return : -1 파라미터 에러
// -2 파일 핸들 에러
// -3 app 검색 실패
// -4 key 검색 실패
// 0 성공
int GetProfileInt(FILE *fp, char *app, char *key, int *ret)
{
char buf[MAX_LENGTH]="";
int n = 0;
// 파라미터 에러
if ( ret == 0 ) return -1;
n = GetProfileString( fp, app, key, buf, sizeof(buf) );
if ( n == 0 )
{
(*ret) = atoi(buf);
return 0;
}
return n;
}
int isBlank(char ch)
{
return ( (ch==0x20) || (ch=='\t') || (ch=='\r') || (ch=='\n') );
}
// 양옆 공백 제거후 리턴
// !원본 문자열을 변경 한다.
char* trim( char *s )
{
char *f=s, *e=0, *c=s;
/* 뒤쪽 공백 제거 */
e=s +(strlen(s)) -1;
while( isBlank(*e) && s<=e) e--;
*(e+1)=0;
/* 앞쪽 공백 제거 */
while( isBlank(*f) && f<=e) f++;
/* 공백 없는 부분 복사 */
if (s!=f) {
while(f<=e) *(c++) = *(f++);
*c=0;
}
return s;
}
포함 된 내용은 아래와 같다.
- trim 함수 사용 (http://newtype.pe.kr/361)
- windows api의 ini 읽는 함수 원형을 흉내 냈다.(MSDN)
사용 설명
설정파일을 읽어 들이기 위한 Lib
Pulibc 함수
int GetProfileString(FILE *fp, char *app, char *key, char *ret, int size);
int GetProfileInt(FILE *fp, char *app, char *key, int *ret);
사용법
FILE *fp=0;
if ((fp=fopen("/home/config/sample.ini", "r")) == 0 )
{
stdout( "File open error! [/home/config/sample.ini]\n" );
return 0;
}
// 서버 정보를 읽는다.
GetProfileString(fp, "SERVER", "TYPE", serverType, sizeof(serverType));
Pulibc 함수
int GetProfileString(FILE *fp, char *app, char *key, char *ret, int size);
int GetProfileInt(FILE *fp, char *app, char *key, int *ret);
사용법
FILE *fp=0;
if ((fp=fopen("/home/config/sample.ini", "r")) == 0 )
{
stdout( "File open error! [/home/config/sample.ini]\n" );
return 0;
}
// 서버 정보를 읽는다.
GetProfileString(fp, "SERVER", "TYPE", serverType, sizeof(serverType));
- ini.h
#ifndef _INI_LIB_HEADER_
#define _INI_LIB_HEADER_
#include <stdio.h>
#include <string.h>
int GetProfileString(FILE *fp, char *app, char *key, char *ret, int size);
int GetProfileInt(FILE *fp, char *app, char *key, int *ret);
#endif
#define _INI_LIB_HEADER_
#include <stdio.h>
#include <string.h>
int GetProfileString(FILE *fp, char *app, char *key, char *ret, int size);
int GetProfileInt(FILE *fp, char *app, char *key, int *ret);
#endif
- ini.c
#include "../inc/ini.h"
#define MAX_LENGTH 256
int GetKeyCount(FILE *fp, char *app);
int seekApp(FILE *fp, char *app);
void getNextKey(FILE *fp, char *retKey, int sizeKey, char *retValue, int sizeValue);
int isBlank(char ch);
char* trim( char *s );
// 현재 fp 부터 검색한다.
// app 위치로 이동한다.
int seekApp(FILE *fp, char *app)
{
char str[MAX_LENGTH] ="";
char buf[MAX_LENGTH] ="";
int bingo;
// 파라이터 오류
if(strlen(app) < 1) return -1;
// 파일 핸들 오류
if(fp == 0) return -2;
sprintf(str, "[%s]", app);
// find app
bingo=0;
while( feof(fp) == 0 )
{
fgets(buf, MAX_LENGTH, fp);
if (buf[0] == 0 || buf[0] == '#') continue;
trim(buf);
if (strncmp(buf, str, strlen(str)) == 0)
{
bingo=1;
break;
}
}
// app 없음
if (bingo==0) return -3;
return 0;
}
// 현재 fp 부터 검색한다.
// 다음 key 값을 얻는다.
void getNextKey(FILE *fp, char *retKey, int sizeKey, char *retValue, int sizeValue)
{
char str[MAX_LENGTH] ="";
char buf[MAX_LENGTH] ="";
char *p=0;
int bingo;
// 파라이터 오류
if( retKey==0 || retValue==0 ) return;
// 파일 핸들 오류
if(fp == 0) return;
// find key
bingo=0;
while( feof(fp) == 0 )
{
fgets(buf, MAX_LENGTH, fp);
trim(buf);
if (buf[0] == 0 || buf[0] == '#') continue;
if (buf[0] == '[' ) return;
break;
}
// 토큰을 찾는다.
p = buf;
while( (*p != '\n') && (*p != '=') && (*p) ) p++;
// value가 있다.
if ( *p == '=' ) bingo = 1;
*p = 0;
// key!!
strncpy(retKey, trim(buf), sizeKey);
retKey[sizeKey-1] = 0;
// value
retValue[0] = 0;
if (bingo == 1)
{
strcpy(str, p+1);
// 토큰을 찾는다.
p = str;
while( (*p != '\n') && (*p) ) p++;
*p = 0;
// value!!
strncpy( retValue, trim(str), sizeValue);
retValue[sizeValue-1] = 0;
}
return;
}
// fp파일에서 [PROC] app를 찾아 key 갯수를 센다.
int GetKeyCount(FILE *fp, char *app)
{
char buf[MAX_LENGTH] ="";
int count=0;
// 파일 핸들 오류
if(fp == 0) return -2;
// 파일의 맨처음으로 이동
fseek(fp, 0L, SEEK_SET);
if ( seekApp(fp, app) != 0 ) return -3;
// count key
count=0;
while( feof(fp) == 0 )
{
fgets(buf, MAX_LENGTH, fp);
trim(buf);
if (buf[0] == '[') break;
if (buf[0] == 0 || buf[0] == '#') continue;
count++;
}
return count;
}
// fp 파일에서 app 카테고리의 key 값을 읽는다.
// ret는 들어갈 값 문자열
// size는 값문자열의 최대 길이
// return : -1 파라미터 에러
// -2 파일 핸들 에러
// -3 app 검색 실패
// -4 key 검색 실패
// 0 성공
int GetProfileString(FILE *fp, char *app, char *key, char *ret, int size)
{
char bufKey[MAX_LENGTH] ="";
char bufValue[MAX_LENGTH] ="";
char *p=0;
int bingo;
// 파라이터 오류
if( (strlen(key) < 1) || ret==0 ) return -1;
// 파일 핸들 오류
if(fp == 0) return -2;
// 파일의 맨처음으로 이동
fseek(fp, 0L, SEEK_SET);
if ( seekApp(fp, app) != 0 ) return -3;
// find key
getNextKey(fp, bufKey, sizeof(bufKey), bufValue, sizeof(bufValue) );
bingo=0;
while( bufKey[0] )
{
if ( strcmp(bufKey, key) == 0 )
{
strncpy( ret, bufValue, size );
ret[size-1]=0;
bingo=1;
break;
}
getNextKey(fp, bufKey, sizeof(bufKey), bufValue, sizeof(bufValue) );
}
// key 없음
if (bingo==0) return -4;
return 0;
}
// fp 파일에서 app 카테고리의 key 값을 읽는다.
// ret는 들어갈 int형 주소
// return : -1 파라미터 에러
// -2 파일 핸들 에러
// -3 app 검색 실패
// -4 key 검색 실패
// 0 성공
int GetProfileInt(FILE *fp, char *app, char *key, int *ret)
{
char buf[MAX_LENGTH]="";
int n = 0;
// 파라미터 에러
if ( ret == 0 ) return -1;
n = GetProfileString( fp, app, key, buf, sizeof(buf) );
if ( n == 0 )
{
(*ret) = atoi(buf);
return 0;
}
return n;
}
int isBlank(char ch)
{
return ( (ch==0x20) || (ch=='\t') || (ch=='\r') || (ch=='\n') );
}
// 양옆 공백 제거후 리턴
// !원본 문자열을 변경 한다.
char* trim( char *s )
{
char *f=s, *e=0, *c=s;
/* 뒤쪽 공백 제거 */
e=s +(strlen(s)) -1;
while( isBlank(*e) && s<=e) e--;
*(e+1)=0;
/* 앞쪽 공백 제거 */
while( isBlank(*f) && f<=e) f++;
/* 공백 없는 부분 복사 */
if (s!=f) {
while(f<=e) *(c++) = *(f++);
*c=0;
}
return s;
}
읽는기능 말고 쓰는기능은 없나요.
소스 보시는 것처럼 읽는 기능 밖에는 없네요.
승훈님이 보완 하셔서 공유해주시면 감사하겠습니다. ^^