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
  • 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
  • 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
Leave a Comment
  • Your email address will not be published. All fields are required.

Top White Papers and Webcasts

  • Live Event Date: October 29, 2014 @ 11:00 a.m. ET / 8:00 a.m. PT Are you interested in building a cognitive application using the power of IBM Watson? Need a platform that provides speed and ease for rapidly deploying this application? Join Chris Madison, Watson Solution Architect, as he walks through the process of building a Watson powered application on IBM Bluemix. Chris will talk about the new Watson Services just released on IBM bluemix, but more importantly he will do a step by step cognitive …

  • Businesses are moving more and more of their customer transactions to the web. Security is understandably a top concern as online transactions increase, so it is important to make sure your electronic signature provider meets the highest security standards. That means more than simply passing a security audit or obtaining a certification. This white paper provides recommendations for taking a broader view of e-signature security, and answers key questions that help identify the security requirements against …

Most Popular Programming Stories

More for Developers

Latest Developer Headlines

RSS Feeds