CIniFile

Environment: VC++ 6.0 All Windows

I had to build an application that uses an ini file. When looking in CodeGuru I found Adam Clauss' class CIniFile. The problem was that it wasn't very intuitive to work with, so I took his idea of the Sections struct and improved it. I'm using the API functions GetPrivateProfileSectionNames, GetPrivateProfileSection, WritePrivateProfileSection, and WritePrivateProfileString. I believe this class is easier to use.

The class has this functions divided by groups and is very easy to use after creating the object call Open( "c:\MyProjects\test.ini") or by calling SetPath("c:\MyProjects\test.ini") call Open(). After that it is straightforward. You should note that unless you set DoNotWrite(), when you change something in the ini file the class will write the contents.

// operation on the sections and keys
int DeleteSection( CString strsectionname);
int DeleteKey( CString sectionname,
               CString delkey);
int AddSection( CString sectionname);
int AddSection( CStringArray mKeys,
                CStringArray mValues,
                CString sectionname);
void AddKey( CString sectionname,
             CString keyname,
             CString value);

// operations on the ini file
void SetPath( CString path);
BOOL Open( CString path);
BOOL Open();
BOOL Write();
void Reset();
void Close();
void DoNotWrite();

// getters
CString GetKeyValue( CString sctionname,
                     CString keyname);
int GetSection( CStringArray &mKeys,
                CStringArray &mValues,
                CString sectionname);
CString GetSection( int sectionIndex);
int GetSetionsSize(){return Sections.GetSize();}
int GetKeysSize( CString sectionname);

// setters
int SetKeyValue( CString sectionname,
                 CString keyname,
                 CString value);

Downloads

Download source - 4 Kb


Comments

  • Win98SE Problems

    Posted by foozy_man on 04/27/2005 05:51pm

    I've been using CIniFile on WinXP with no problem, but it's not working on Win98SE. Does anyone know why? And what do I have to change to make it work? Thanks.

    Reply
  • My contribute

    Posted by Legacy on 10/10/2003 12:00am

    Originally posted by: Filipe Freitas


    As I was testing this class after reading all the comments listed and after making some corrections. I was prepared to test with an INI file I've found in other INI file handler class.

    TEST.INI used in my tests

    ; Header comment test.
    ; for 16-bit app support

    [drivers]
    wave=mmdrv.dll
    timer=timer.drv

    [mci]
    [driver32]
    [386enh]
    ; This is a test comment for 386enh
    woafont=dosapp.FON
    EGA80WOA.FON=EGA80WOA.FON
    EGA40WOA.FON=EGA40WOA.FON
    CGA80WOA.FON=CGA80WOA.FON
    ; This is another test comment for 386enh
    CGA40WOA.FON=CGA40WOA.FON
    FileSysChange=off
    [ScreenTime]
    Password Value=0
    previousProjectorProcessID=1724


    Using an experimental project as I describe:


    m_pIniFile = new CIniFile(_T("C:\\temp\\TEST.INI"));

    int nKey, nSection = 0;
    CString strSection;
    CString strDisplay;
    CStringArray mKeys;
    CStringArray mValues;

    while ((strSection=m_pIniFile->GetSection(nSection)) != NULLSTR)
    {
    strDisplay.Format(_T("[%s]"),strSection);
    m_display.AppendString(strDisplay);
    m_pIniFile->GetSection(mKeys,mValues,strSection);
    for (nKey=0; nKey <= mKeys.GetUpperBound(); nKey++)
    {
    strDisplay = mKeys[nKey]+_T("=")+mValues[nKey];
    m_display.AppendString(strDisplay);
    }
    nSection++;
    }

    .
    .

    delete m_pIniFile;

    PS: m_display is an CEdit derived class that allows me to append string using ::ApendString(CString& strText) method. Thanks to Ravi Bhavnani ( ravib@datablast.net ) by his CHistoryEdit class

    I've got the following display results:


    [drivers]
    wave=mmdrv.dll
    timer=timer.drv
    [mci]
    wave=mmdrv.dll
    timer=timer.drv
    [driver32]
    wave=mmdrv.dll
    timer=timer.drv
    [386enh]
    woafont=dosapp.FON
    EGA80WOA.FON=EGA80WOA.FON
    EGA40WOA.FON=EGA40WOA.FON
    CGA80WOA.FON=CGA80WOA.FON
    CGA40WOA.FON=CGA40WOA.FON
    FileSysChange=off
    [ScreenTime]
    Password Value=0
    previousProjectorProcessID=1724


    Looking at the results something seemmed very strange to me, because [driver], [mci] and [driver32] sections had the same key entries(?!). That happened because mValues and mKeys were used more than once and if after a nonblank section appears a blank section, this last one will kept same values for mValues and mKeys because they were not cleanned up!
    So I rewrote the code in the following way...


    int CIniFile::GetSection(CStringArray &mKeys, CStringArray &mValues, CString sectionname)
    {
    int sectionIndex = GetSectionIndex(sectionname);
    int nSectionKeys = (sectionIndex > NOTFOUND) ?
    Sections[sectionIndex].Keys.GetSize() : 0;

    mKeys.SetSize(nSectionKeys);
    mValues.SetSize(nSectionKeys);

    for(int i = 0; i < nSectionKeys; i++)
    {
    mKeys[i] = Sections[sectionIndex].Keys[i];
    mValues[i] = Sections[sectionIndex].Values[i];
    }
    return sectionIndex;
    }


    I think this is almost bullet proof. :)

    PS: I love this class!!!

    Reply
  • How to read file of integer ?

    Posted by Legacy on 04/26/2003 12:00am

    Originally posted by: ldtvn

    there is a text file which contains all integer . For example,
    test.txt
    1 2 3
    4 5 6
    7 8 9
    Please show me a program which can read these number ?

    Reply
  • GetSection bug

    Posted by Legacy on 04/02/2003 12:00am

    Originally posted by: Thomas Moore

    I recently had to upgrade some old code that used INI files and I used your CIniFile object. Thanks for putting it together. It has been very useful. 
    
    

    However, I did find one issue you might want to be aware of. Below are two code snippets. The first is your original code as I downloaded it from http://www.codeguru.com/ The second is the same code after I made a small change. In your version, the function will always return on the first time through the loop and the array will always only have the first item.

    Yours
    int CIniFile::GetSection(CStringArray &mKeys, CStringArray &mValues, CString sectionname)
    {
    int sectionIndex = GetSectionIndex(sectionname);
    if(sectionIndex > NOTFOUND)
    {
    for(int i = 0;i < Sections[sectionIndex].Keys.GetSize();i++)
    {
    mKeys.SetSize(i + 1) ;
    mValues.SetSize( i + 1) ;
    mKeys[i] = Sections[sectionIndex].Keys[i];
    mValues[i] = Sections[sectionIndex].Values[i];
    return sectionIndex;
    }
    }
    return NOTFOUND;
    }

    What I changed it to
    int CIniFile::GetSection(CStringArray &mKeys, CStringArray &mValues, CString sectionname)
    {
    int sectionIndex = GetSectionIndex(sectionname);
    if(sectionIndex > NOTFOUND)
    {
    for(int i = 0;i < Sections[sectionIndex].Keys.GetSize();i++)
    {
    mKeys.SetSize(i + 1) ;
    mValues.SetSize( i + 1) ;
    mKeys[i] = Sections[sectionIndex].Keys[i];
    mValues[i] = Sections[sectionIndex].Values[i];
    }
    }
    return sectionIndex;
    }

    Reply
  • Bug...

    Posted by Legacy on 07/18/2002 12:00am

    Originally posted by: Francois ENOT

    I'm very surprised nobody noticed the following bug which make this class unusable :

    in function SetKeyValue :

    section is updated this way, which changes the name of the key instead of its value :

    Sections[sectionIndex].Keys[keyIndex] = value;

    correct line should be :

    Sections[sectionIndex].Values[keyIndex] = value;


    Thanks for sharing your good code anyway ;-)
    Francois

    Reply
  • Problem with empty .ini file !

    Posted by Legacy on 03/26/2002 12:00am

    Originally posted by: gpanda

    Adding new section to a empty .ini file will cause problem.

    when i add a new section to a new empty .ini file
    , cause illegal access violation.

    I found some code is wrong:

    int CIniFile::AddSection(CString sectionname)
    {
    int sectionIndex = GetSectionIndex(sectionname);
    int sectionsize = Sections.GetSize() ;
    sectionsize++;
    if(sectionIndex == NOTFOUND)
    {
    Sections.SetSize(sectionsize) ;
    Sections[sectionsize].SectionName =
    //^^^^^^^^^^^^
    sectionname;
    }
    return sectionsize;
    }

    Sections[sectionsize].SectionName should be
    Sections[sectionsize-1].SectionName !
    Should it's be 0 index?

    It seems many statement have the same problem...

    (Sorry for my poor English!!)

    Reply
  • Bad Code

    Posted by Legacy on 03/04/2002 12:00am

    Originally posted by: Roger McElfresh

    int CIniFile::GetSection(CStringArray &mKeys, CStringArray &mValues, CString& sectionname)
    
    {
    int sectionIndex = GetSectionIndex(sectionname);
    if(sectionIndex > NOTFOUND)
    {
    for(int i = 0;i < Sections[sectionIndex].Keys.GetSize();i++)
    {
    mKeys.SetSize(i + 1) ;
    mValues.SetSize( i + 1) ;
    mKeys[i] = Sections[sectionIndex].Keys[i];
    mValues[i] = Sections[sectionIndex].Values[i];
    }
    return sectionIndex;
    }
    return NOTFOUND;
    }

    Move "return sectionIndex" out of "for" loop.

    Reply
  • Class can only be used in MFC programs...

    Posted by Legacy on 02/28/2002 12:00am

    Originally posted by: Paul McKenzie

    This is a good class, however it can only be used in MFC programs because of the CString and CStringArray classes.

    Next time, use std::string and vector<string> to make the class useable for MFC and non-MFC Windows programs.

    Reply
  • General remark (apply not only to this author)

    Posted by Legacy on 02/28/2002 12:00am

    Originally posted by: Ron Hashimshony

    Class wizzard adds an include to the CWinApp derived class.
    When publishing a source only files, you need to get rid of it first...

    In this case this is the line -
    #include "TestIni.h"

    Reply
  • solution for ini versus registry: apply them both

    Posted by Legacy on 02/28/2002 12:00am

    Originally posted by: Guy

    Hi GIl;
    i saw your class and it's nice.
    but not supply a lot of features.
    one of the major feature that your class should provide is a function that do the follow:
    Func(INI_FILE_NAME,PLACE_IN_REGISTRY);
    this function should export the ini file into the registery.
    and another function:
    Func1(PLACE_IN_REGISTRY,INI_FILE_NAME);
    and this function import from registry into an ini file.
    i think that if you will add this functions you wil have a perfect CIniFile.
    if you will do pls let me know
    rgrds
    GEliyahu

    Reply
Leave a Comment
  • Your email address will not be published. All fields are required.

Top White Papers and Webcasts

  • Managing your company's financials is the backbone of your business and is vital to the long-term health and viability of your company. To continue applying the necessary financial rigor to support rapid growth, the accounting department needs the right tools to most efficiently do their job. Read this white paper to understand the 10 essentials of a complete financial management system and how the right solution can help you keep up with the rapidly changing business world.

  • Live Event Date: August 20, 2014 @ 1:00 p.m. ET / 10:00 a.m. PT When you look at natural user interfaces as a developer, it isn't just fun and games. There are some very serious, real-world usage models of how things can help make the world a better place – things like Intel® RealSense™ technology. Check out this upcoming eSeminar and join the panel of experts, both from inside and outside of Intel, as they discuss how natural user interfaces will likely be getting adopted in a wide variety …

Most Popular Programming Stories

More for Developers

Latest Developer Headlines

RSS Feeds