(C++) Class for reading Windows-INI-like files

Post those lines of code you feel like sharing or find what you require for your project here; or simply use them as tutorials.
Masterhawk
Posts: 299
Joined: Mon Nov 27, 2006 6:52 pm
Location: GERMANY
Contact:

Post by Masterhawk »

Unfortunatly not :(
This "bug" occurs in every line. For a time it worked to cut off the last two signs...but now it doesn't....i'm veeeeeeery confused....
Image
Sylence
Posts: 725
Joined: Sat Mar 03, 2007 9:01 pm
Location: Germany
Contact:

Post by Sylence »

me 2 ^^
Could you please send me your code and your ini file?
Software documentation is like sex. If it's good you want more. If it's bad it's better than nothing.
Masterhawk
Posts: 299
Joined: Mon Nov 27, 2006 6:52 pm
Location: GERMANY
Contact:

Post by Masterhawk »

you got pm...;)
Image
vizzy
Posts: 10
Joined: Mon May 21, 2007 2:55 pm
Location: Dresden, Germany

Post by vizzy »

thanks, great code 8)
MasterGod
Posts: 2061
Joined: Fri May 25, 2007 8:06 pm
Location: Israel
Contact:

Post by MasterGod »

So is it fixed? Everything working as it should?
Image
Dev State: Abandoned (For now..)
Requirements Analysis Doc: ~87%
UML: ~0.5%
L1zb3th
Posts: 15
Joined: Thu Jul 26, 2007 1:27 am

Post by L1zb3th »

ohhhhhh, i hated that class xDDD
for windows users, try this :


IniReader.h

Code: Select all


#ifndef INIREADER_H
#define INIREADER_H
class CIniReader
{
public:
 CIniReader(char* szFileName);
 int ReadInteger(char* szSection, char* szKey, int iDefaultValue);
 float ReadFloat(char* szSection, char* szKey, float fltDefaultValue);
 bool ReadBoolean(char* szSection, char* szKey, bool bolDefaultValue);
 char* ReadString(char* szSection, char* szKey, const char* szDefaultValue);
private:
  char m_szFileName[255];
};
#endif//INIREADER_H


IniWriter.h

Code: Select all

#ifndef INIWRITER_H
#define INIWRITER_H
class CIniWriter
{
public:
 CIniWriter(char* szFileName);
 void WriteInteger(char* szSection, char* szKey, int iValue);
 void WriteFloat(char* szSection, char* szKey, float fltValue);
 void WriteBoolean(char* szSection, char* szKey, bool bolValue);
 void WriteString(char* szSection, char* szKey, char* szValue);
private:
 char m_szFileName[255];
};
#endif //INIWRITER_H
Ini.h

Code: Select all

#ifndef INI_H
#define INI_H
#include <Windows.h>
#include <Stdio.h>
#include "IniReader.h"
#include "IniWriter.h"

/*******************************************************************************
# INI READER
*******************************************************************************/
CIniReader::CIniReader(char* szFileName)
{
 memset(m_szFileName, 0x00, 255);
 memcpy(m_szFileName, szFileName, strlen(szFileName));
}
int CIniReader::ReadInteger(char* szSection, char* szKey, int iDefaultValue)
{
 int iResult = GetPrivateProfileInt(szSection,  szKey, iDefaultValue, m_szFileName);
 return iResult;
}
float CIniReader::ReadFloat(char* szSection, char* szKey, float fltDefaultValue)
{
 char szResult[255];
 char szDefault[255];
 float fltResult;
 sprintf(szDefault, "%f",fltDefaultValue);
 GetPrivateProfileString(szSection,  szKey, szDefault, szResult, 255, m_szFileName);
 fltResult =  atof(szResult);
 return fltResult;
}
bool CIniReader::ReadBoolean(char* szSection, char* szKey, bool bolDefaultValue)
{
 char szResult[255];
 char szDefault[255];
 bool bolResult;
 sprintf(szDefault, "%s", bolDefaultValue? "True" : "False");
 GetPrivateProfileString(szSection, szKey, szDefault, szResult, 255, m_szFileName);
 CharLower(szResult);
 bolResult =  (strcmp(szResult, "true") == 0) ? true : false;
 return bolResult;
}
char* CIniReader::ReadString(char* szSection, char* szKey, const char* szDefaultValue)
{
 char* szResult = new char[255];
 memset(szResult, 0x00, 255);
 GetPrivateProfileString(szSection,  szKey, szDefaultValue, szResult, 255, m_szFileName);
 return szResult;
}


/*******************************************************************************
# INI WRITER
*******************************************************************************/



CIniWriter::CIniWriter(char* szFileName)
{
 memset(m_szFileName, 0x00, 255);
 memcpy(m_szFileName, szFileName, strlen(szFileName));
}
void CIniWriter::WriteInteger(char* szSection, char* szKey, int iValue)
{
 char szValue[255];
 sprintf(szValue, "%d", iValue);
 WritePrivateProfileString(szSection,  szKey, szValue, m_szFileName);
}
void CIniWriter::WriteFloat(char* szSection, char* szKey, float fltValue)
{
 char szValue[255];
 sprintf(szValue, "%f", fltValue);
 WritePrivateProfileString(szSection,  szKey, szValue, m_szFileName);
}
void CIniWriter::WriteBoolean(char* szSection, char* szKey, bool bolValue)
{
 char szValue[255];
 sprintf(szValue, "%s", bolValue ? "True" : "False");
 WritePrivateProfileString(szSection,  szKey, szValue, m_szFileName);
}
void CIniWriter::WriteString(char* szSection, char* szKey, char* szValue)
{
 WritePrivateProfileString(szSection,  szKey, szValue, m_szFileName);
}
#endif //INI_H
Enjoy !
My Gramathicalz horrorz are precalkulated, zo Zhut Up !
_______
Bah, actually my english is poor, but...
forget it xDDDD
Sylence
Posts: 725
Joined: Sat Mar 03, 2007 9:01 pm
Location: Germany
Contact:

Post by Sylence »

I moved the class to my new website. (Avaible here)
I redesigned it, fixed some bugs and made some minor speed improvements.

@L1zb3th
I know that it works this way, but it's everything but plattform-independent.
Last edited by Sylence on Sat Dec 27, 2008 8:05 pm, edited 1 time in total.
Software documentation is like sex. If it's good you want more. If it's bad it's better than nothing.
MasterGod
Posts: 2061
Joined: Fri May 25, 2007 8:06 pm
Location: Israel
Contact:

Post by MasterGod »

Its just too good :D.
Its a MUST BE in the next release (1.4)!! MUST!

Awesome Job!
MasterGod
Posts: 2061
Joined: Fri May 25, 2007 8:06 pm
Location: Israel
Contact:

Post by MasterGod »

Hi, I'm having troubles with the writing methods of this class.
I've downloaded the latest version from the site and tried this code with the following results:

Code: Select all

bool CConfigManager::saveChanges()
{
	switch(deviceParam.DriverType)
	{
	case EDT_SOFTWARE: ini->addKeyToSection("Settings","DriverType","EDT_SOFTWARE");
		break;
	case EDT_BURNINGSVIDEO: ini->addKeyToSection("Settings","DriverType","EDT_BURNINGSVIDEO");
		break;
	case EDT_DIRECT3D8: ini->addKeyToSection("Settings","DriverType","EDT_DIRECT3D8");
		break;
	case EDT_DIRECT3D9: ini->addKeyToSection("Settings","DriverType","EDT_DIRECT3D9");
		break;
	case EDT_OPENGL: ini->addKeyToSection("Settings","DriverType","EDT_OPENGL");
		break;
	default: ini->addKeyToSection("Settings","DriverType","EDT_NULL");
	}

	stringc winSize = deviceParam.WindowSize.Width;
	winSize += "x";
	winSize += deviceParam.WindowSize.Height;
	ini->addKeyToSection("Settings","WindowSize",winSize.c_str());

	ini->setSaveFileName(iniFilePath);
	return ini->save();
}
config.ini wrote: [Settings]
DriverType=EDT_OPENGL
WindowSize=800x600
Bits=32
Fullscreen=false
Stencilbuffer=false
Vsync=false
AntiAlias=false
HighPrecisionFPU=false
EDT_DIRECT3D8=ֽֽֽֽֽֽֽֽֽֽֽֽֽֽֽֽֽֽֽֽֽֽֽֽֽֽֽֽֽֽֽֽֽֽֽֽֽֽֽֽֽֽֽֽֽֽֽֽֽֽֽֽֽֽֽֽֽֽֽֽֽֽֽֽ‎‎‎‎
1024x768=ֽֽֽֽֽֽֽֽֽֽֽֽֽֽֽֽֽֽֽֽֽֽֽֽֽֽֽֽֽֽֽֽֽֽֽֽֽֽֽֽֽֽֽֽֽֽֽֽֽֽֽֽֽֽֽֽֽֽֽֽֽֽֽֽ‎‎‎‎


*Notice those few new empty lines..
And there is a problem that if there isn't a new empty line at the end of the file it can't read it right. -I don't care much about this cause its a simple new empty line but if it will be fixed I'll be pretty glad :wink:

Except that, Thank you very much for your class, its very helpful and I'm using it in my project.
Image
Dev State: Abandoned (For now..)
Requirements Analysis Doc: ~87%
UML: ~0.5%
bull
Posts: 36
Joined: Wed Sep 12, 2007 8:49 am
Location: s1Ng4p0R3

Post by bull »

Why don't you use lua? It's even cross-platform. The syntax will not be as nice as INI though
My name is bull, for we are many ...
MasterGod
Posts: 2061
Joined: Fri May 25, 2007 8:06 pm
Location: Israel
Contact:

Post by MasterGod »

I've never used lua and for some reason I don't want to :lol:..
I really like this class and I like working with it..
Image
Dev State: Abandoned (For now..)
Requirements Analysis Doc: ~87%
UML: ~0.5%
Sylence
Posts: 725
Joined: Sat Mar 03, 2007 9:01 pm
Location: Germany
Contact:

Post by Sylence »

Yeah I know about this bug and to be honest I didn't figure out yet why the file is read wrong if there is no new line at the end of the file.
I'll try to fix this when I have more time to work on it (maybe in 2 weeks or so)

@bull When you only need configuration files lua is overkill.

oh and btw you can pass a dimension2d directy to setValue() ;)
Software documentation is like sex. If it's good you want more. If it's bad it's better than nothing.
MasterGod
Posts: 2061
Joined: Fri May 25, 2007 8:06 pm
Location: Israel
Contact:

Post by MasterGod »

Sylence wrote:Yeah I know about this bug and to be honest I didn't figure out yet why the file is read wrong if there is no new line at the end of the file.
I'll try to fix this when I have more time to work on it (maybe in 2 weeks or so)

@bull When you only need configuration files lua is overkill.

oh and btw you can pass a dimension2d directy to setValue() ;)
Didn't noticed SValue2Di(core::dimension2di); -> cool.

The /n @ eof bug isn't as important as the not-working writing methods.
Maybe you didn't understand me but when I write to the file it just add what after the '=' and some garbage to the end of the file instead of editing an existing key with the new values - see me post above for clarification.

P.S
Thanks for not abandoning this project. Its really useful especially when working with irrlicht, very nice and clean code, I really like it and learn from it a lot.




TWO WEEK!?.. Please can you speed it up, I know its only 2 weeks and I'm making it sounds like a year but I don't wanna have any wholes in my project, when I finish a category (as all configuration handling classes for example) I want it done bugless (as much as I can) before I move to the next part which means two weeks of cleaning up to a pretty cleaned up code..
Image
Dev State: Abandoned (For now..)
Requirements Analysis Doc: ~87%
UML: ~0.5%
Sylence
Posts: 725
Joined: Sat Mar 03, 2007 9:01 pm
Location: Germany
Contact:

Post by Sylence »

damn I really have to make a test programm for it... in the CIniFileReaderStub::addKeyToSection() there is the line (CIniFileReaderStub.cpp , line 260)

Code: Select all

if(value)
		strncpy(k->Name,value,64);
change it to

Code: Select all

if(value)
		strncpy(k->Value,value,64);
and it should work fine. At least it does on my machine...

Going to update the source on the site tomorrow
Software documentation is like sex. If it's good you want more. If it's bad it's better than nothing.
MasterGod
Posts: 2061
Joined: Fri May 25, 2007 8:06 pm
Location: Israel
Contact:

Post by MasterGod »

Nice, it clears the garbage but this is the config file I get after changing it:
config.ini wrote: [Settings]
DriverType=EDT_OPENGL
WindowSize=800x600
Bits=32
Fullscreen=false
Stencilbuffer=false
Vsync=false
AntiAlias=false
HighPrecisionFPU=false
DriverType=EDT_DIRECT3D8
WindowSize=1024x768

It adds to the end instead of editing the existing keys. Still adding 2 new lines at the end (except the /n to make it work)

P.S
It was line 256 not 260 on my machine..
Image
Dev State: Abandoned (For now..)
Requirements Analysis Doc: ~87%
UML: ~0.5%
Post Reply