现在的位置: 首页 > 综合 > 正文

读写ini文件

2013年10月12日 ⁄ 综合 ⁄ 共 6180字 ⁄ 字号 评论关闭

读写ini文件 2008-04-22 17:14:35
分类: C/C++

Windows中有一种比较特殊的文本文件,就是ini文件,该文件是一种结构化的文本文件,主要用来保存简单的配置信息,比如windows中的win.ini,system.ini等都是这种类型的文件,你可以用记事本等文本编辑器打开它并进行查看修改。

Windows为了很好的读写这类文件,提供了一些专门的读写函数,我们在自己的应用程序中可以充分的利用这些函数来保存一些比较简单的配置信息。

Windows的ini文件结构一般如下:
; 注释部分,以分号开头
[Section1]
key1=name1
key2=name2
;每个节(section)以方括号括起来,每个section下面可以有0到多个key
;以key=value的形式书写,=前面是key的名称,=后面是key的value
[Section2]
key3=value3
key4=value4

从上面可以看出一个ini文件主要有3部分组成,以分号开始的注释,以方括号括起来的节(section)以及在每个节下面的以key=value形式的键,在同一个section下面key的名称必须唯一,在不同的section下面可以相同,在整个ini文件中section的名称不能重复。

ini文件的结构很简单,下面的程序,演示了如何用windows提供的api进行读写.
新建一个VC6++win32的空的工程,添入以下文件:

/*    
     FileName: ini.c
     Function: Read and write ini file
     Desc:     Windows 32 bits Application

     本程序演示了如何读写ini文件,ini文件是一种特殊的文本文件,它的结构如下:
     ; comment
     [Section1]
     Key1=value1
     Key2=value2
     [Section2]
     ;keys
     Key3=value3
     Key4=value4
     ......
*/

#include <windows.h>
#include "resource.h"

HWND    hWinMain = NULL; // 主对话框句柄
char    szProfileName[MAX_PATH]; // 用来保存ini文件的全路径名称
char    szBuffer1[32760]; // 用来保存读取的Sections
char    szBuffer2[32760]; // 用来保存读取的Keys

char    szFileName[] = TEXT("\\Option.ini"); // ini 文件名称
char    szSecPos[] = TEXT("Windows Position");
char    szKeyX[] = TEXT("X");
char    szKeyY[] = TEXT("Y");
char    szFmt1[] = TEXT("%d");
char    szFmtSection[] = TEXT("[%s]");
char    szCrLf[] = "\r\n"; // 回车换行

void    EnumIni(); // 读取ini文件,枚举所有的sections以及keys
void    GetPosition(); // 获取对话框的坐标
void    SavePosition(); // 保存对话框的坐标

LRESULT CALLBACK DialogProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);

int WINAPI WinMain(IN HINSTANCE hInstance, IN HINSTANCE hPrevInstance, IN LPSTR lpCmdLine, IN int nShowCmd )
{
    DialogBoxParam(hInstance, MAKEINTRESOURCE(IDD_MAIN), NULL, DialogProc, 0);
    return 0;
}

void EnumIni()
{
    char    szBuffer[256];
    char    *p, *q;

    SetDlgItemText(hWinMain, IDC_INI, NULL);
    // 得到所有的sections,每个section都是以0结尾的字符串,最后整个字符串以0结尾
    GetPrivateProfileSectionNames(szBuffer1, sizeof(szBuffer1), szProfileName);
    p = szBuffer1; // 指向szBuffer1中的第一个Section

    while ( p[0] ) // 循环读取section
    {
        wsprintf(szBuffer, szFmtSection, p);
        SendDlgItemMessage(hWinMain, IDC_INI, EM_REPLACESEL, (WPARAM)FALSE, (LPARAM)szBuffer);
        SendDlgItemMessage(hWinMain, IDC_INI, EM_REPLACESEL, (WPARAM)FALSE, (LPARAM)szCrLf);
       
        // 得到该Section下面的所有keys
        // 每个key都是以0结尾的字符串,最后整个字符串以0 结尾
        GetPrivateProfileSection(p, szBuffer2, sizeof(szBuffer2), szProfileName);
        q = szBuffer2; // 指向第一个key
        while ( q[0] ) // 循环读取所有的keys
        {
            SendDlgItemMessage(hWinMain, IDC_INI, EM_REPLACESEL, (WPARAM)FALSE, (LPARAM)q);
            SendDlgItemMessage(hWinMain, IDC_INI, EM_REPLACESEL, (WPARAM)FALSE, (LPARAM)szCrLf);
            q += strlen(q) + 1; // 指针移动到下一个key
        }
        p += strlen(p) + 1; // 指针移动到下一个section
    }
}

void GetPosition()
{
    int        x, y;
   
    // 获取当前的路径
    GetCurrentDirectory(MAX_PATH, szProfileName);
    // 得到ini文件的全路径
    lstrcat(szProfileName, szFileName);

    // 得到位置section的坐标值,如果失败,则默认为(50, 50)
    x = GetPrivateProfileInt(szSecPos, szKeyX, 50, szProfileName);
    y = GetPrivateProfileInt(szSecPos, szKeyY, 50, szProfileName);
   
    // 设置对话框的位置
    SetWindowPos(hWinMain, HWND_TOP, x, y, 0, 0, SWP_NOSIZE);
}

void SavePosition()
{
    char    szBuffer[512];
    RECT    rc;

    // 得到窗口的坐标, 并切保存到ini文件
    GetWindowRect(hWinMain, &rc);
    wsprintf(szBuffer, szFmt1, rc.left);
    WritePrivateProfileString(szSecPos, szKeyX, szBuffer, szProfileName);
    wsprintf(szBuffer, szFmt1, rc.top);
    WritePrivateProfileString(szSecPos, szKeyY, szBuffer, szProfileName);
}

LRESULT CALLBACK DialogProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    char    szSection[256];
    char    szKey[256];
    char    szValue[256];
    char    szBuffer[256];
       
    switch ( uMsg )
    {
    case WM_CLOSE: // 对话框关闭保存对话框的位置
        SavePosition();
        EndDialog(hWnd, 0);
        break;
    case WM_INITDIALOG: // 对话框初始化,得到对话框的原来位置,并且读取ini文件
        hWinMain = hWnd;
        GetPosition();
        EnumIni(); // 枚举ini文件的内容
        break;
    case WM_COMMAND:
        GetDlgItemText(hWnd, IDC_SEC, szSection, sizeof(szSection));
        GetDlgItemText(hWnd, IDC_KEY, szKey, sizeof(szKey));
        GetDlgItemText(hWnd, IDC_VALUE, szValue, sizeof(szValue));
        switch ( LOWORD(wParam) )
        {
        case IDC_SEC:
        case IDC_KEY:
        case IDC_VALUE:
        case IDC_INI:
            return TRUE;
        case IDC_DEL_SEC: // 删除一个section
            WritePrivateProfileString(szSection, NULL, NULL, szProfileName);
            break;
        case IDC_DEL_KEY: // 删除一个key
            WritePrivateProfileString(szSection, szKey, NULL, szProfileName);
            break;
        case IDC_SET_KEY: // 保存一个key
            WritePrivateProfileString(szSection, szKey, szValue, szProfileName);
            break;
        case IDC_GET_KEY: // 得到一个key
            GetPrivateProfileString(szSection, szKey, NULL, szBuffer, sizeof(szBuffer), szProfileName);
            SetDlgItemText(hWnd, IDC_VALUE, szBuffer);
            break;
        default:
            break;
        }
        EnumIni(); // 更新ini文件的显示信息
        break;
    default:
        return FALSE;
    }
    return TRUE;
}

//resource.h
#define IDD_MAIN                        101
#define IDC_SEC                         1000
#define IDC_KEY                         1001
#define IDC_VALUE                       1002
#define IDC_DEL_SEC                     1003
#define IDC_DEL_KEY                     1004
#define IDC_GET_KEY                     1005
#define IDC_SET_KEY                     1006
#define IDC_INI                         1007

// ini.rc
#include "resource.h"
#include "afxres.h"
//
// Dialog
//

IDD_MAIN DIALOG DISCARDABLE  0, 0, 290, 222
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "读写Ini文件"
FONT 10, "宋体"
BEGIN
    RTEXT           "Section",IDC_STATIC,14,18,33,8
    RTEXT           "Key",IDC_STATIC,12,42,35,8
    RTEXT           "Value",IDC_STATIC,12,66,35,8
    EDITTEXT        IDC_SEC,58,15,110,14,ES_AUTOHSCROLL
    EDITTEXT        IDC_KEY,58,37,110,14,ES_AUTOHSCROLL
    EDITTEXT        IDC_VALUE,58,61,111,14,ES_AUTOHSCROLL
    PUSHBUTTON      "删除&Section",IDC_DEL_SEC,178,14,50,14
    PUSHBUTTON      "删除&Key",IDC_DEL_KEY,233,14,50,14
    PUSHBUTTON      "读取K&ey",IDC_GET_KEY,178,37,50,14
    PUSHBUTTON      "保存Ke&y",IDC_SET_KEY,233,37,50,14
    LTEXT           "当前ini文件内容:",IDC_STATIC,7,88,73,8
    EDITTEXT        IDC_INI,7,103,276,112,ES_MULTILINE | ES_AUTOVSCROLL |
                    ES_AUTOHSCROLL | ES_READONLY | WS_VSCROLL | WS_HSCROLL
END

关于上面用的api函数的具体用法,你可以参看msdn,上面有详细的解释。
本文程序改写自罗云彬32位汇编语言一书中的例程。
author:cnhnyu
e-mail:cnhnyu<AT>gmail<DOT>com
qq:94483026

抱歉!评论已关闭.