상세 컨텐츠

본문 제목

C++: WIN API, MFC - INI(확장자.ini) 파일 일고, 쓰기

프로그래밍 관련/MFC

by AlrepondTech 2020. 9. 10. 04:30

본문

반응형

 

 

 

 

=======================

=======================

=======================

 

 

 

 

출처: http://moople.tistory.com/62

 

 

 

  • 저장 대상 정보는 사용자 신상, 위치, 크기, 옵션, 사용자의 설정, 최근 연 파일 목록 및 기타 동작에 필요한 모든 정보들이다.
  • 단, 이런 설정 정보는 프로그램 자신의 정보일 뿐이지 사용자의 정보는 아니다.
  • INI 파일은 섹션, 키, 키값으로 구성되어 있는 단순한 텍스트 파일이며 메모장으로 열어 보면 쉽게 그 내용을 확인할 수 있고 편집도 가능하다.
  •    
  • INI 파일 구성

   

 

   

  • 섹션 : 정보의 종류에 따라 나누어 놓은 키의 그룹
  • 키 : 저장할 정보의 이름
  • 키 값 : 저장된 데이터

   

   

   

   

  • 관련 함수
    • BOOL WritePrivateProfileString( LPCTSTR lpAppName, LPCTSTR lpKeyName, LPCTSTR lpString, LPCTSTR lpFileName );
      • INI 파일에 정보를 저장할 때 쓰인다.
       
    • lpAppName
      • 정보를 기록할 섹션 이름을 지정 한다.
    • lpkeyName
      • 정보를 기록할 키 이름을 지정하며 없을 경우 만든다.
    • lpString
      • 키 값을 정의하는 문자열이다.
    • lpFileName
      • INI 파일명을 지정한다.
      • 경로를 지정할 수 있다.
    • 저장이 성공할 경우 TRUE를 리턴하고 실패할 경우 에러값을 리턴한다.   
    •    
    • UINT GetPrivateProFileInt( LPCTSTR lpAppname, LPCTSTR lpKeyName INT nDefault, LPCTSTR lpFileName );
      • 정수로 되어있는 키 값을 읽어올 때 사용한다.
      • 파일을 읽어올 때 해당 파일이나 섹션이나 키가 없을 경우 디폴트 값으로 불러 올 수 있다.
      • nDefault
        • 지정한 디폴트 값을 읽는다.
      • 해당 키값을 리턴한다.   
      •    
    • DWORD GetPrivateProFileString( LPCTSTR lpAppName, LPCTSTR lpKeyName, LPCTSTR lpDefault, LPTSTR lpReturnedString, DWORD nSize, LPCTSTR lpFileName );
      • 문자열로 되어 있는 키 값을 읽어올 때 사용한다.
      • 파일을 읽어올 때 해당 파일이나 섹션이나 키가 없을 경우 디폴트 값으로 불러 올 수 있다.
      • lpReturnedString
        • 읽은 문자열을 대입받을 버퍼
      • nSize
        • 읽어올 버퍼의 크기이다.
      • 불러올 문자열의 개수를 리턴한다.   
      •    
    • 이밖에도 WriteProFileString, GetProfileInt, GetProfileString 이 있지만 WIN.ini 에 저장하고 불러오는 함수로 윈도우 설정 상태를 저장 하는 Ini에서 작업을 할 수 있는데 자칫 잘못하면 윈도우 시스템을 건드릴 수 있으므로 사용하지 않는다.

   

   

  • 단점
    • INI 파일은 텍스트 파일 포맷으로 저장되므로 사용자가 임의로 조작할 수 있다. 이말은 사용자의 실수로 잘못조작하게 되면 프로그램이 오작동할 가능 성이 높다는 얘기다.
    • 프로그램당 하나 이상의 INI파일을 생성하므로 하드 디스크에는 무수한 INI 파일들로 꽉 차게되고 결과적으로 하드 디스크 동간을 낭비한다.
    • INI 파일은 복수 사용자를 지원하지 않으므로 사용자별로 설정한 정보를 별도로 저장할 수 없다. 또한 한 프로그램에 대해서도 복수 버전에 대한 정보를 분리 저장하기 어렵다.
    • INI 파일이 손상되었을 경우에 복구할 수 있는 방법이 없다. 일반적으로 INI 파일에 저장되는 정보들은 프로그램 실행에 꼭 필요한 정보들이기 때문에 최악의 경우는 프로그램을 다시 설치해야 하는 경우도 있다.
    • INI 파일은 실제 디스크상에 존재하는 텍스트 파일이므로 정보를 읽고 쓸 때마다 하드 디스크를 액세스 해야 한다. 그래서 속도가 무척 느리다.

 



출처: http://moople.tistory.com/62 [무플방지의 묵회블로그]

 

 

 

 

=======================

=======================

=======================

 

 

 

 

출처: http://blog.naver.com/nikky6/3304791

 

 

1. INI 파일이란...간단히 말하면 응용 프로그램이 실행될 때 필요한 초기화 정보를 담고있는 파일 (INItialization file) 이다. 16 bit 윈도우즈 응용 프로그램들은 대부분 실행파일명과 동일한 이름을 가진 INI 파일을 가지고 있으며 윈도우즈 자신도 win.ini 라는 초기화 파일을 가지고 있다. 아스키 파일이므로 일반 텍스트 편집기로 쉽게 내용을 확인할 수 있고 그 속에 담긴 정보의 의미를 정확히 이해할 수 있는 경우라면 간단히 수정할 수도 있다. 보통 윈도우즈 디렉토리나 응용 프로그램이 설치된 디렉토리에 존재한다.2. INI 파일에는 무엇을 기록하는가?꼭 무엇을 기록해야 하는가는 중요치 않다. 프로그래머가 필요하다고 생각되는 정보는 무엇이든 기록할 수 있다. 일반적으로는 최근에 불러왔던 파일들의 목록, 최근에 실행되었을 때의 윈도우 위치와 모양등을 기록하며 그 외에는 프로그램에 따라 달라진다. 예를 들어, 우리가 사용하는 DevStudio는 프로그램 실행시 이전에 종료하기 전 작업상태 그대로를 유지하여 시작할 수 있는 옵션이 있는데 이런 일에도 사용할 수 있는 것이다.3. INI 파일의 구성INI 파일은 다음의 세부분으로 구성된다. 섹션 (section), 키 (key), 값 (value)
예를들어 어떤 게임 프로그램에서 상위 10등 이내에 든 사람의 이름을 ini 파일에 기록한다면 이런 식이 될 것이다.

[SCORE] <--- 섹 션: SCORE
1등=밤사람 <--- 키: 1등, 값: 밤사람
2등=홍길동 <--- 키: 2등, 값: 홍길동
3등=나삼등 <--- 키: 3등, 값: 나삼등
... ...

4. INI 파일에서 정보를 가져오기.WIN 32 API는 INI 파일에서 정보를 읽어내는 것과 관련 4개의 함수를 제공한다. 아래에 함수들의 원형이 소개되어 있다.DWORD GetProfileString( LPCTSTR lpAppName, LPCTSTR lpKeyName, LPCTSTR lpDefault, LPTSTR lpReturnedString, DWORD nSize );
UINT GetProfileInt( LPCTSTR lpAppName, LPCTSTR lpKeyName, INT nDefault );
DWORD GetPrivateProfileString( LPCTSTR lpAppName, LPCTSTR lpKeyName, LPCTSTR lpDefault, LPTSTR lpReturnedString, DWORD nSize, LPCTSTR lpFileName );
UINT GetPrivateProfileInt( LPCTSTR lpAppName, LPCTSTR lpKeyName, INT nDefault, LPCTSTR lpFileName );

 

크게 2가지로 분류해 볼 수 있을 것이다. 하나는 데이터 타입으로 구분된다는 점이고 또 하나는 private이냐 아니냐 하는 점이다.
GetProfileString()과 GetProfileInt()는 win.ini 파일에, GetPrivateProfileString()과 GetPrivateProfileInt()은 프로그래머가 정의한 ini 파일에 정보를 읽고 쓴다. 함수들의 인자를 자세히 살펴보면 바로 파일명을 전달하는 인자가 있고 없는 차이뿐이다.

API 라이브러리나 DevStudio의 온라인 도움말을 참조하면 함수들의 인자에 대한 자세한 설명이 나와있다. 여기서는 앞에서 예로 들었던 게임점수 기록을 가지고 간단히 설명하겠다.

strName = GetPrivateProfileString( "SCORE", "1등", "기록없음", "c:\\game\\score.ini" );

이것은 "c:\game\score.ini" 파일을 열고 "SCORE" 섹션중 "1등" 이라는 키에 기록되어 있는 값을 읽어 strName 이라는 변수에 저장하라는 말이다. GET 함수들은 읽어낸 값(문자열의 경우 null종료문자를 뺀) 반환한다. 만일 해당 파일이나 섹션, 키가 존재하지 않거나 기록된 값이 없다면 기본값으로 "기록없음"을 사용하라는 뜻이다.
추가로 파일명에 경로가 사용되지 않으면 프로그램은 해당 파일을 윈도우즈 디렉토리에서 찾게 된다. 물론 경로가 쓰인다면 해당 경로에서 파일을 찾게된다.

nScore = GetPrivateProfileInt( "SCORE", "1등점수", 0, "score.ini" );

이것은 읽어내야할 값이 정수라는 차이 밖에 없다. 나머지는 string을 대상으로한 함수와 동일하다.

strName = GetProfileString( "SCORE", "1등", "기록없음" ); nScore = GetProfileInt( "SCORE", "1등점수", 0 );

여기엔 파일명이 없다. 작업 대상이 되는 파일이 무조건 win.ini가 되기 때문이다. 대개는 윈도우즈가 설정한 값들을 이용하기 위해 사용하지만 여러분이 원한다면 개인적인 정보도 win.ini에 두고 사용할 수 있다.

5. INI 파일에 정보를 기록하기.WIN 32 API는 INI 파일에 정보를 기록하는 것과 관련 2개의 함수를 제공한다. 아래에 함수들의 원형이 소개되어 있다.BOOL WritePrivateProfileString( LPCTSTR lpAppName, LPCTSTR lpKeyName, LPCTSTR lpString, LPCTSTR lpFileName );
BOOL WriteProfileString( LPCTSTR lpAppName, LPCTSTR lpKeyName, LPCTSTR lpString );

읽기함수들과 달리 쓰는 함수엔 정수형을 위한 함수가 없다. 모두 문자로 처리되기 때문이고 어차피 읽기함수가 그것을 문자로 읽을 것인지 아니면 숫자로 읽을 것인지를 처리해 주므로 아무 문제가 없다.

WritePrivateProfileString( "SCORE", "1등", strName, "c:\\game\\score.ini" ); WritePrivateProfileString( "SCORE", "1등점수", strScore, "c:\\game\\score.ini" );

이것은 "c:\game\score.ini" 파일을 열고 "SCORE" 섹션중 "1등" 키에는 "strName" 변수에 저장된 값을, "1등점수" 키엔 "strScore" 변수에 저장된 값을 기록하라는 뜻이다. 물론 숫자형태의 점수는 문자열로 먼저 변환시켜야 할 것이다. 여기서도 nScore를 strScore로 변형했다.
win.ini를 대상으로한 함수는 설명하지 않아도 되겠죠?

6. 기타① 정수형이 아닌 수의 처리는 어떻게 할까? 예를들어 float형이라든가 하는...
API가 완벽하다고는 할 수 없지만 대개는 제공하지 않는 함수가 있다면 분명히 다른 방법이 있기 때문이다. 이 경우에도 처음부터 숫자 데이터를 읽지말고 문자열로 읽어낸 후에 원하는 변수형으로 전환시키면 된다. 그럼 문자를 숫자로 어떻게...? 게으르기는! C 또는 C++의 문자열처리 함수(또는 클래스)를 찾아보~아.② 새로운 섹션이나 키를 만들려면...
값을 기록하는 함수들을 그냥 사용하면 된다. 쓰기 함수들은 기록하려는 섹션이나 키가 없다면 새로 만들어서 값을 기록하기 때문이다.③ 기록했던 섹션을 지우려면...
특별히 섹션을 지우는 함수는 없다. 그러나 방법은 있다. 기록함수에서 키네임을 전달하는 두번째 인자의 값으로 null을 주면 된다. 이렇게...WritePrivateProfileString( "SCORE", NULL, "", "score.ini" );

INI 파일의 모든 섹션을 순서대로 정리하고 싶다면 기록하기 전에 이 방법으로 지우고 나서 기록을 하면 될 것이다.

④ 섹션이나 키를 지정할 때 대소문자를 구분해야 하는가?
섞어써도 상관없다. 즉, 대소문자를 구분하지 않는다.

***************************************************************************************

private과 아닌 함수의 차이는 win.ini에는 private가 없는걸 쓰고 자기가 짠프로그램에는 있는걸

쓰면 된다고 DevStudio에 나와 있단다..

***************************************************************************************

※ 참고 : INI 파일의 정의와 기록형식, 기록내용 등은 초기화 파일 (*.INI)과 읽고 쓰는 API 함수를 보세요.1. 응용 프로그램의 INI 파일 : 표준 INI (standard INI)Win 95' 이래 INI 파일의 사용은 윈도우즈 레지스트리로 대체되었지만 탐색기로 윈도우즈 디렉토리를 열어보면 *.ini 파일을 많이 볼 수 있는데 그것은 아직도 INI 파일이 사용되고 있다는 얘기다.윈도우즈 디렉토리에 있는 INI 파일들의 이름은 대개 응용 프로그램의 이름과 같다. 예를들어 넷스케이프를 사용하고 있다면 그곳에서 netscape.ini 파일을 볼 수 있을 것이다.
응용 프로그램의 INI 파일은 보통 윈도우즈 디렉토리에 만들어지며 그 응용 프로그램의 실행에 관련된 정보를 기록하여 두었다가 실행시에 사용하게 된다. 간단한 예를 든다면 툴바의 위치나 응용 프로그램이 최근에 실행될 때의 창의 크기나 상태 그리고 최근에 열었던 파일의 목록등을 기록하는 것이다.
MFC를 사용하여 만든 응용 프로그램에서는 CWinApp 클래스가 응용 프로그램의 INI 파일을 관리하는 몇 개의 멤버함수들을 제공해 주는데 특별한 지시가 없는 한 응용 프로그램의 INI 파일을 대상으로 정보를 기록하거나 읽어오게 되며 응용 프로그램이 처음 실행될 때 윈도우즈 디렉토리에 만들어지게 된다.
2. 읽고 쓰는 함수들앞서 말했듯이 MFC의 CWinApp 클래스엔 다음과 같은 멤버함수들이 있다.사용법은 간단하다. 모두 3개씩의 인자를 가지고 있는데 처음 두개중 lpszSection은 섹션명을, lpszEntry는 해당 섹션의 키를 지정한다. 세번째 인자는 읽는 함수들의 경우 INI 파일이 없거나 있더라도 지정된 섹션이나 키가 없을경우 기록된 값 대신 사용할 디폴트 값이며 쓰는 함수들의 경우엔 해당 키에 기록할 값을 넣어주면 된다.
함수들의 리턴값은 쓰는 함수들의 경우 쓰기가 성공하면 '0'이 아닌 값, 실패하면 '0'이 되고 읽는 함수들의 경우 읽어낸 또는 디폴트로 지정한(읽기를 실패한 경우) 정수 또는 문자열이다.

※ 참고:
값을 기록하기 위해 지정한 섹션이나 키가 존재하지 않는다면 새로 만들어진다. 만약 이미 만들어진 섹션이나 키를 지우려면 WriteProfileString() 함수의 세번째 인자로 NULL을 지정하면 된다. 그리고 섹션이나 키 네임은 대소문자를 구분하지 않는다.

3. 지정된 INI 파일 바꾸기CWinApp 클래스의 데이터 멤버 중엔 m_pszProfileName이 있는데 바로 이 변수에 응용 프로그램이 사용할 INI 파일명이 담겨 있다.   public:   const char* m_pszProfileName;
만약 응용 프로그램이 사용할 INI 파일의 경로나 이름을 바꾸고 싶다면 이 변수에 원하는 경로와 파일명을 넣어주면 되는데 그 전에 해야할 일이 있다.
m_pszProfileName은 위에 보인대로 char형 포인터 변수이다. 응용 프로그램이 시작되고 CWinApp 가 생성되면 이 변수가 가리키는 문자열을 저장할 메모리는 힙 상에 동적으로 할당된다. 따라서 새로 문자열을 지정하려면 먼저 이전에 할당된 메모리를 해제하고 다시 메모리를 할당해야 한다. 다음이 그 과정이다.
첫번째 메모리 할당은 CWinApp 클래스의 InitInstance()가 실행되기 전에 이루어지므로 다시 지정하기 위한 위의 두 줄은 InitInstance() 멤버에 넣어주면 될 것이다.
이 때 주의할 점은 만약 InitInstance()에 응용 프로그램의 INI 파일을 사용하는 코드가 있다면 그 코드의 앞에서 재지정이 이루어져야 한다는 것이다. 그렇지 않을 경우엔 당연히 INI 파일에서 쓰거나 읽은 데이터가 엉뚱한 것이 될 수도 있다.
예를든다면, InitInstance() 함수엔 응용 프로그램이 최근에 열었던 파일목록을 읽어오기 위해 CWinApp 클래스의 LoadStdProfileSettings() 멤버를 둘 수 있는데 이 함수가 호출된 뒤에 응용 프로그램의 INI 파일을 바꾸어버리면 응용 프로그램을 종료할 때 다시 기록되는 최근 파일목록은 어떻게 변경되든 상관없이 다시 프로그램이 실행될 때 읽혀지지 않을 것이다.
[출처] ini파일사용하기..|작성자 니키식스

 

 

 

=======================

=======================

=======================

 

 

 

출처: http://acpi.tistory.com/17

 

 

 

/*

INI 파일은 Section, Key, Value 로 구성된다.

파일이 없으면 만들어진다.

 

쓰기 함수 : WritePrivateProfileString 

읽기 함수 : GetPrivateProfileString

*/

 

#include <iostream>

#include <windows.h>

 

using namespace std;

 

int main()

{

char szBuffer[256];

 

char szFileName[256] = "Config.ini";

char szSection[256] = "System";

char szKey[256] = "ServerIP";

 

// 쓰기

WritePrivateProfileString(

szSection, 

szKey,

"192.100.0.1",

szFileName);

 

// 읽기

GetPrivateProfileString(

szSection,

szKey,

"",

szBuffer,

256,

szFileName);

 

cout << szBuffer << endl;

return 0;

}

 



출처: http://acpi.tistory.com/17 [Test Code]

 

 

 

 

=======================

=======================

=======================

 

 

 

 

출처: http://blog.naver.com/PostView.nhn?blogId=charmingode&logNo=120146801671

 

 

파일의 경로나 가끔 변경되는 값을 위해 하드코딩하는 경우, 시간이 많이 지나고 나면 수정이 어렵다.

또는 관리자가 교체될 경우, 이전 관리자가 미리 지정해놓은 설정값만 변경하면 되게 하기 위해 ini파일을 주로 사용한다.

 

1. ini파일의 형식

ini파일의 형식은 다음과 같다.

( datat.ini 中 )

 

[section1] 

key1 = 헬로우

key2 = 바이바이

 

[section2]

main = www.naver.com

blog = blog.naver.com/charmigode

괄호[]로 묶인 section1 부분이 섹션

key1처럼 = 기점으로 나뉜 앞 문자열이 

= 뒤 문자열이 이다.

 

( * 아래 함수들은 mfc에서 기본으로 참조하는 winbase.h에서 선언된 함수들이기 때문에 별도의 헤더파일 참조가 필요없다 )

 

2. ini파일의 쓰기

WritePrivateProfileString()으로 ini파일에 키=값을 설정할 수 있다. 

만약 Int형이라면 WritePrivateProfileInt().

BOOL WritePrivateProfileString(
  LPCTSTR lpAppName,     // [Section1]과 같은 섹션
  LPCTSTR lpKeyName,     // key1과 같은 키

  LPCTSTR lpString,           // key1에 해당하는 값

  LPCTSTR lpFileName      // ini파일의 경로

);

예를 들어 위에 설정한 ini파일에서 section1에 해당하는 key1에 값을 변경해보자.

WritePrivateProfileString( "section1", "key1", "헬로헬로헬로헬로헬로", ".\\Data.ini");

요로코롬 하면 sectino1의 key1값이 변경된다.

4번째 파라미터는 ini파일의 경로인데 보통 절대경로를 써줘야 정확하지만, 위에서는 상대경로를 사용했다.

(상대경로 : 현재소스가 들어있는 폴더에 Data.ini가 있다면 . \\ Data.ini를 기입한다. ( . : 현재 폴더, \\: \를 소스상에서 표시하기 위해 \\ 사용)

 

(+ 플러스 내용)

만약 해당하는 키가 없을 때 위 함수를 실행하면, 키와 값이 새로 생성된다.

 

3. ini파일의 읽기

GetPrivateProfileString()으로 ini파일에서 키에 해당하는 값을 가져올 수 있다.

만약 Int형이라면 GetPrivateProfileInt().

 DWORD GetPrivateProfileString(
  LPCTSTR lpAppName,       // [section1]과 같은 섹션

  LPCTSTR lpKeyName,       // key1과 같은 키

  LPCTSTR lpDefault,           // 섹션이름이나 키이름을 찾지 못하면 출력할 디폴트 값
  LPTSTR lpReturnedString,  // 값을 저장할 버퍼

  DWORD nSize,                  // 값을 저장할 버퍼의 사이즈
  LPCTSTR lpFileName        // ini파일의 경로
);

예를 들어 위에 설정한 ini파일에서 section1에 해당하는 key1에 값을 가져와보자.

 TCHAR data1[256]; 

 

GetPrivateProfileString( "section1", "key1", "default", data1, 256, ".\\Data.ini");

요로코롬 해주면 data1에는 key1값에 해당하는 헬로우 값이 들어가게 된다.

 

 

4. 섹션 또는 키 삭제

섹션이나 키의 삭제가 필요한 경우에는 다음과 같이 실행한다.

 

1) key1의 값을 삭제할 경우

 WritePrivateProfileString( "section1", "key1", NULL, ".\\Data.ini");

그 결과

key1=

이렇게 값란이 비어있음을 확인할 수 있다.

 

마찬가지로 section1을 삭제 할경우

WritePrivateProfileString( "section1", NULL, NULL, ".\\Data.ini"); 

 

5. ini 파일의 섹션 읽기를 이용하여 모든 키 읽기

키 값을 모르니 섹션에 있는 모든 키 다 불러서 확인하고 싶을때 !

GetPrivateProfileSection()을 적절히 이용한다.

 

진행중인 프로젝트를 진행하다가 한 섹션에 어떤 키 값이 있는지 알 수 없고, 모든 키 값을 불러와야 할 경우가 있었다.

그럴 땐 다음과 같이 했다.

 

   TCHAR s_section[4096] ={0}; //섹션 아래의 모든 값을 저장할 버퍼
  TCHAR s_key[256] = {0x00,}; //한 줄을 읽어 저장할 버퍼(키:값)
  int pos = 0; //한 줄의 인덱스 위치

 

 //nSize = 그 섹션의 모든 값 하나하나의 수.
  DWORD nSize = GetPrivateProfileSection(L"section1", s_section, 4096, ".\\Data.ini");
  BOOL bSection = false; // 한 줄을 모두 확인했으면 true하여, pos를 0으로 초기화해서 다음 줄을 읽을 준비
  bool bEqul = false; //'='으로 키와 값을 분리


  //i는 모든 섹션의 인덱스 위치이고, pos는 한 줄의 인덱스 위치
  for(int i = 0; i < (int)nSize; i++, pos++)
  {
   if(s_section[i] != '\0') //문자가 있을 경우
   {
    if(s_section[i] != '=' && bEqul == false)
    {
     if(bSection) pos = 0;
     memcpy(s_key + pos, s_section+i, sizeof(s_key+pos)-2); //=이전값인 키를 저장
     bSection = FALSE;
     continue;
    }
    else bEqul = true; // 문자가 =인 경우
   }
   else //없을경우 ( 키의 끝 / 섹터의 끝)
   {
    AfxMessageBox(s_key);  //모든 키 값을 출력!!!

    

   //s_key 초기화
    s_key[i] = '\0';
    memset(s_key, 0x00, sizeof(s_key));
    bSection = true;
    bEqul = false;
   }
  }

요로코롬 하면 지정한 섹션(section1)의 모든 키 값을 출력할 수 있다.

원리는 GetPrivateProfileSection()이 지정한 섹션아래 모든 값을 읽어오기 때문에

그 받아온 값을 분석하여 '='을 기준으로 키와 값으로 생각하여 각각 특정 버퍼에 저장한다.

 

코드를 이해하면 약간의 응용도 가능하다.

 

다음 예제는 섹션아래 키와 값을 구별하여 출력

 

  TCHAR s_section[4096] ={0}; //섹션 아래의 모든 값을 저장할 버퍼
  TCHAR s_key[256] = {0x00,}; //한 줄을 읽어 저장할 버퍼(키)
  TCHAR s_data[256] = {0x00,}; //한 줄을 읽어 저장할 버퍼(값)
  int key_pos = 0; //한 줄의 키의 인덱스 위치
  int data_pos =0; //한 줄의 값의 인덱스 위치

 

  //nSize = 그 섹션의 모든 값 하나하나의 수.
  DWORD nSize = GetPrivateProfileSection(L"section1", s_section, 4096, ".\\Data.ini");
  BOOL bSection = false; // 한 줄을 모두 확인했으면 true하여, pos를 0으로 초기화해서 다음 줄을 읽을 준비
  bool bEqul = false; //'='으로 키와 값을 분리. =지나면 true해서 구분


  //i는 모든 섹션의 인덱스 위치이고, pos는 한 줄의 인덱스 위치
  for(int i = 0; i < (int)nSize; i++)
  {
   if(s_section[i] != '\0') //문자가 있을 경우
   {
    if(s_section[i] != '=' )
    {
     if(bSection){
      key_pos = 0;
      data_pos =0;
      bSection = FALSE;
     }

     if( bEqul == false) //=이전 문자는 바로 키
     {
      memcpy(s_key + key_pos, s_section+i, sizeof(s_key+key_pos)-2); //=이전값인 키를 저장
      key_pos++;
     }
     else  //=이후 문자는 바로 값
     {
      memcpy(s_data + data_pos, s_section+i, sizeof(s_data+data_pos)-2);
      data_pos++;
     }
    }
    else //문자가 =인 경우
     bEqul = true;
   }
   else //없을경우 ( 키의 끝 / 섹터의 끝)
   {
    AfxMessageBox(s_key);    

    AfxMessageBox(s_data);

   

 //s_key 초기화
    s_key[i] = '\0';
    s_data[i] = '\0';
    memset(s_key, 0x00, sizeof(s_key));
    memset(s_data, 0x00, sizeof(s_data));
    bSection = true;
    bEqul = false;
   }
  }

 이런 식으로 하면 섹션아래의 키의 개수, 몇 번째 위치의 키의 값 다양한 응용 가능

[출처] INI 파일 관리 읽기.쓰기|작성자 JW

 

 

 

반응형

 

728x90

 

 

 

=======================

=======================

=======================

 

 

 

 

 

출처: http://myblue0324.tistory.com/93

 

 

INI파일은 어플리케이션의 설정을 내보내거나 읽어올때 혹은 어플리케이션 시작 시 초기정보를 읽어올때 흔히 쓰이는 파일 포맷입니다.

다음은 이러한 INI 파일포맷을 다루는 예제입니다.

1. 예제 INI 파일문서(sample.ini).

view plaincopy to clipboardprint?

  1. [Server]  
  2. IP=127.0.0.1  
  3. PORT=23  
  4. ID=admin  
  5. PASSWORD=1234  

INI 파일은 섹션, 키, 값 으로 구성되어 있으며 위의 INI파일은 "Server 섹션의 IP 키의 값은 127.0.0.1" 이러한 방식으로 이해하면 됩니다. 마찬가지로 "Server 섹션의 PORT 키의 값은 23" 이렇게도 물론 가능합니다.

2. INI 파일작성.
INI 파일작성은 섹션, 키, 값에 해당하는 정보를 입력하여 WritePrivateProfileString() API 함수를 통해 작성이 가능합니다.
WritePrivateProfileString(섹션, 키, 값, INI파일경로)

view plaincopy to clipboardprint?

  1. CString strINIPath(_T("D:\\sample.ini"));  
  2. CString strSection, strKey, strValue;  
  3.   
  4. strSection = _T("Server");   // 섹션  
  5.   
  6. strKey = _T("IP");     // 키  
  7. strValue = _T("127.0.0.1");   // 값  
  8. WritePrivateProfileString(strSection, strKey, strValue, strINIPath);  
  9.   
  10. strKey = _T("PORT");  
  11. strValue = _T("23");  
  12. WritePrivateProfileString(strSection, strKey, strValue, strINIPath);  
  13.   
  14. strKey = _T("ID");  
  15. strValue = _T("admin");  
  16. WritePrivateProfileString(strSection, strKey, strValue, strINIPath);  
  17.   
  18. strKey = _T("PASSWORD");  
  19. strValue = _T("1234");  
  20. WritePrivateProfileString(strSection, strKey, strValue, strINIPath);  

3. INI 파일파싱.
INI 파일파싱은 섹션, 키에 해당하는 정보를 입력하여 GetPrivateProfileString() API 함수를 통해 해당 정보에 대한 값의 파싱이 가능합니다.
GetPrivateProfileString(섹션, 키, 디폴트값, 값을 읽어올 버퍼, 버퍼크기, INI파일경로)

view plaincopy to clipboardprint?

  1. TCHAR szBuf[MAX_PATH]={0,};  
  2. CString strINIPath(_T("D:\\sample.ini"));  
  3. CString strSection, strKey, strValue;  
  4.   
  5. strSection = _T("Server");   // 섹션  
  6.   
  7. strKey = _T("IP");     // 키  
  8. GetPrivateProfileString(strSection, strKey, _T(""), szBuf, MAX_PATH, strINIPath);  
  9. strValue.Format(_T("%s"), szBuf); // 값  
  10.   
  11. strKey = _T("PORT");  
  12. GetPrivateProfileString(strSection, strKey, _T(""), szBuf, MAX_PATH, strINIPath);  
  13. strValue.Format(_T("%s"), szBuf);  
  14.   
  15. strKey = _T("ID");  
  16. GetPrivateProfileString(strSection, strKey, _T(""), szBuf, MAX_PATH, strINIPath);  
  17. strValue.Format(_T("%s"), szBuf);  
  18.   
  19. strKey = _T("PASSWORD");  
  20. GetPrivateProfileString(strSection, strKey, _T(""), szBuf, MAX_PATH, strINIPath);  
  21. strValue.Format(_T("%s"), szBuf);  



출처: http://myblue0324.tistory.com/93 [나만의 상상력]

 

 

 

 

=======================

=======================

=======================

 

 

 

 

출처: http://terrorjang.tistory.com/18

 

 

사용 계기 

 - Login 시 서버에 접속 전에 PC에서 사용자 인증을 1차적으로 거치기 위해서 ini파일에 ID, Password를 저장 후 인증하도록 함.

  - 개인 PC의 보안 접속을 위해 PC에서 미리 인증된 ID로만 접속 하도록 하기 위함.

 

 

1.ini 파일

우선 ini 파일이 무엇인지 알아야 한다.

 

- 정의

INI(Initialization) 파일 포맷은 설정 파일에 대한 de facto 표준이다. INI 파일은 단순 구조의 텍스트 파일로 이루어져 있다. 보통 마이크로소프트 윈도와 연결되어 있지만 다른 운영 체제에서도 사용할 수 있다. "INI 파일"이라는 이름은 ".INI"라는 파일 확장자가 따라오지만, ".CFG", ".conf", ".TXT" 등의 다른 확장자를 사용하기도 한다.

 

- 형식

매개 변수

INI 파일에 포함된 기본 요소는 매개 변수이다. 각 변수는 이름과 값을 가지고 있으며 등호로 이를 구분한다. "이름"은 등호 왼쪽에 적는다.

이름(키) =

섹션

매개 변수는 임의의 이름으로 지정된 여러 개의 섹션으로 구분할 수 있다. 이 섹션 이름은 괄호 ([, ])로 구분한다.

[섹션]

주석

세미콜론 (;)은 주석의 시작을 가리킨다. 줄이 끝날 때까지 주석을 계속 적을 수 있다. 세미콜론 사이의 모든 항목과 줄의 끝 부분까지의 내용은 프로그램의 설정값에서 무시한다.

; 주석

 

가상의 프로그램(실제로 존재하지는 않음)을 위한 INI 파일의 예는 다음과 같다. 두 개의 섹션을 가지고 있으며, 그 가운데 한 섹션은 소프트웨어의 소유자에 대한 것이며, 나머지 하나는 종업원 명부 데이터베이스 연결에 대한 것이다. 또, 파일을 마지막으로 수정한 날짜,도메인 이름 대신 IP 주소가 쓰인 까닭에 대해 주석을 적고 있다.

; 홍길동이 2001년 4월 1일에 마지막으로 수정하였음 [owner] name=홍길동 organization=최고의 제품 [database] server=192.0.2.62 ; 네트워크 이름 변환이 동작하지 않는 경우 IP 주소를 사용한다 port=143 file="payroll.dat"

 

출처 위키백과 : https://ko.wikipedia.org/wiki/INI_%ED%8C%8C%EC%9D%BC

 

 

 

 

1-1. WritePrivateProfileString()

BOOL WINAPI WritePrivateProfileString(

  __in  LPCTSTR lpAppName,

  __in  LPCTSTR lpKeyName,

  __in  LPCTSTR lpString,

  __in  LPCTSTR lpFileName

);

 

ini파일에 data를 쓰기 위한 함수

 

[Parameter]

lpAppName [in]

어떤 섹션에 기록될것인지 입력합니다. 

lpKeyName [in]

어떤 키에 기록될것인지 입력합니다. 만약 NULL일때는 섹션 내의 모든 정보를 삭제합니다.

lpString [in]

키에 들어가는 값을 입력합니다. 꼭 NULL종료 문자열이여야 합니다. 정수, 실수등의 값은 문자열로 바꾸어서 넣어주어야 하고, 만약 NULL일때는 키를 삭제합니다.

lpFileName [in]

어떤 파일에 기록할지 입력합니다. 경로를 지정하지 않으면, 윈도우즈 디렉토리 (보통 C:\Windows\)에 생성됨.

 

2-2.GetPrivateProfileString()

DWORD WINAPI GetPrivateProfileString(

  __in   LPCTSTR lpAppName,

  __in   LPCTSTR lpKeyName,

  __in   LPCTSTR lpDefault,

  __out  LPTSTR lpReturnedString,

  __in   DWORD nSize,

  __in   LPCTSTR lpFileName

);

 

[Parameter]

 

lpAppName [in]

어떤 섹션을 읽을지 지정합니다. .

lpKeyName [in]

어떤 키를 읽을지 지정합니다.

lpDefault [in]
읽을수 없을때 어떤 값이 디폴트로 될지 지정합니다.
lpReturnedString [out]

문자열 버퍼의 주소를 줍니다.

nSize [in]

lpReturnedString의 사이즈를 줍니다.

lpFileName [in]

어떤 ini에서 읽을지 지정합니다.

 

 

 

적용

 

BOOL CALLBACK InfoDlgProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)

{

char str[100] = "test1234";

SYSTEMTIME st;

 

switch(uMsg){

case WM_INITDIALOG:

WritePrivateProfileString("LOGIN", "ID","test", "c:\\login.ini");

WritePrivateProfileString("LOGIN", "PASSWORD","1234","c:\\login.ini");

return TRUE;

case WM_CLOSE:

EndDialog(hDlg, NULL);

}

return FALSE;

}

 

- Test 결과 파일이 없는 상태에서도 WritePrivateProfileString() 를 사용하면 파일 생성 및 data 입력이 가능 하다.

- 경로를 적지 않을 경우 "c:\windows" 폴더에 생성됨을 확인.

 

 

 

 



출처: http://terrorjang.tistory.com/18 [개발자 공간]

 

 

 

=======================

=======================

=======================

 

 

 

반응형


관련글 더보기

댓글 영역