Reading from a configuration file
Now I have a good working environment, I have started to develop a gaming engine based around Erik Yuzwa's PeonEngine (http://www.gameprogrammingstarttofinish.wazooinc.com/) and Tim Jones' game engine tutorial (http://www.sdltutorials.com/sdl-tutorial-basics/). One of my requirements was the ability to configure the game engine using a configuration file. This initially looked to be quite simple as a function was already available, but still took several hours to work the way I wanted it to - all because of UNICODE.
By default unicode is automatically enabled in Visual C++ 2010 and to convert sting (char*) variables proved quite tasking. In the end though I had learn't that unicode can be disabled by setting the project properties "Configuration Properties --> General --> Project Defaults --> Charater Set" to "Not Set".
The function to read values from the configuration file is called GetPrivateProfileString or GetPrivateProfileInt. In unicode the functions pass wide characters (16 bit - 2 bytes) and therefore a normal char variable would require conversion. One way around this issue is to pass the string with an 'L' prefix (i.e. L"New String").
Example Unicode GetPrivateProfileString funciton
DWORD dwStatus = 0;
TCHAR strReturnString[260];
ZeroMemory( &strTemp, sizeof( strTemp ) );
dwStatus = GetPrivateProfileString(L"APPLICATION",L"STRING_VALUE", L"ERROR", strReturnString, 260, lpFilename);
Even though I could pass wide strings I preferred to use char's as this was easier to understand and debug for a beginner such as myself. The following code is a stand-alone solution with unicode turned off, this will be incorporated into my game engine classes.
Config.ini - Configuration File
[FIRST_VALUES]
INTEGER_VALUE=800
STRING_VALUE=ABC
[SECOND_VALUES]
BOOL_VALUE=TRUE
FLOAT_VALUE=9.87654
iniReader - Configuration File Reader Code
/*!
\file iniReader.cpp
\brief My First Steps : C++ Game Development - ini Confuration File Reader
A Configuration File Reader demo allows for Strings, Integers, Boolean and Floats.
NOTE : UNICODE HAS BEEN DISABLED!
\author Matt Wakeling
\date 25th May 2010
*/
#include <Windows.h>
#include <string>
using namespace std;
/// DECLARATION : Declare Int2String Function.
string Int2String(int intNumber);
/// DECLARATION : Declare Float2String Function.
string Float2String(float number);
/// DECLARATION : Declare GetStringValue Function.
string GetStringValue(LPCTSTR lpApp, LPCTSTR lpKeyName, LPCTSTR lpFilename, LPCTSTR lpDefault);
/// DECLARATION : Declare GetIntegerValue Function.
UINT GetIntegerValue(LPCTSTR lpApp, LPCTSTR strKeyName, LPCTSTR lpFilename, int iDefault);
/// DECLARATION : Declare GetBoolValue Function.
bool GetBoolValue(LPCTSTR lpApp, LPCTSTR lpKeyName, LPCTSTR lpFilename, LPCTSTR lpDefault);
/// DECLARATION : Declare GetFloatValue Function.
float GetFloatValue(LPCTSTR lpApp, LPCTSTR lpKeyName, LPCTSTR lpFilename, LPCTSTR lpDefault);
/*!
\brief DEFINITION : Define main function, allows arguments to be passed.
DESCRIPTION : C++ Main code entry point, no arguements have been passed to the function.
\param argc - Set the number of arguements passed to the function.
\param argv[] - Array of arguements passed to the function.
\return int - Returns an integer value to show completion status (0 = Successful).
*/
int main(int argc, char* argv[])
{
/// COMMENT : Start Function.
/// COMMENT : Get String value from Configuration File.
printf("lpApp : %s\n","FIRST_VALUES");
printf("lpKey : %s\n","STRING_VALUE");
printf("lpFilename : %s\n","C:\\Config.ini");
printf("Return Value (String) : %s\n",GetStringValue("FIRST_VALUES", "STRING_VALUE", "C:\\Config.ini","ERROR").c_str());
printf("\n");
/// COMMENT : Get Integer value from Configuration File.
printf("lpApp : %s\n","FIRST_VALUES");
printf("lpKey : %s\n","INTEGER_VALUE");
printf("lpFilename : %s\n","C:\\Config.ini");
printf("Return Value (Integer) : %s\n",Int2String(GetIntegerValue("FIRST_VALUES", "INTEGER_VALUE", "C:\\Config.ini",-1)).c_str());
printf("\n");
/// COMMENT : Get Boolean value from Configuration File.
printf("lpApp : %s\n","SECOND_VALUES");
printf("lpKey : %s\n","BOOL_VALUE");
printf("lpFilename : %s\n","C:\\Config.ini");
if (GetBoolValue("SECOND_VALUES", "BOOL_VALUE", "C:\\Config.ini","FALSE"))
printf("Return Value (Bool) : %s\n","TRUE");
else
printf("Return Value (Bool) : %s\n","FALSE");
printf("\n");
/// COMMENT : Get Float value from Configuration File.
printf("lpApp : %s\n","SECOND_VALUES");
printf("lpKey : %s\n","FLOAT_VALUE");
printf("lpFilename : %s\n","C:\\Config.ini");
printf("Return Value (Float) : %s\n",Float2String(GetFloatValue("SECOND_VALUES", "FLOAT_VALUE", "C:\\Config.ini","0.0")).c_str());
/// COMMENT : Exit Program and Return no errors code (0 = Successful).
return 0;
/// COMMENT : End Function.
}
/*!
\brief DEFINITION : Define convert integer to string function.
DESCRIPTION : Converts integer values to string, so the number can be output via PRINTF.
\param intNumber - Integer value requiring conversion.
\return string - String value of converted output.
*/
string Int2String(int intNumber)
{
if (intNumber == 0)
return "0";
string strTemp="";
string strReturnValue="";
while (intNumber>0)
{
strTemp+=intNumber%10+48;
intNumber/=10;
}
for (int i=0;i<strTemp.length();i++)
strReturnValue+=strTemp[strTemp.length()-i-1];
return strReturnValue;
}
/*!
\brief DEFINITION : Define convert Float to string function.
DESCRIPTION : Converts float values to string, so the number can be output via PRINTF.
\param fltNumber - Float value requiring conversion.
\return string - String value of converted output.
*/
string Float2String(float fltNumber)
{
char* strTest = new char[MAX_PATH];
int intResult = 0;
intResult = _snprintf_s(strTest, MAX_PATH, MAX_PATH, "%f", fltNumber);
return (string) strTest;
}
/*!
\brief DEFINITION : Define get string value from configuration file function.
DESCRIPTION : Gets a string value from a configuration file.
\param lpApp - Application header in configuration file [APPLICATION].
\param lpKeyName - Key name in configuration file KEYNAME=.
\param lpFilename - File name and path for the configuration.
\param lpDefault - Default string return value.
\return string - String value from configuration file.
*/
string GetStringValue(LPCTSTR lpApp, LPCTSTR lpKeyName, LPCTSTR lpFilename, LPCTSTR lpDefault)
{
DWORD dwResult = 0;
CHAR strReturn[MAX_PATH];
dwResult = GetPrivateProfileString(lpApp, lpKeyName, lpDefault, strReturn, MAX_PATH, lpFilename);
return strReturn;
}
/*!
\brief DEFINITION : Define get integer value from configuration file function.
DESCRIPTION : Gets an integer value from a configuration file.
\param lpApp - Application header in configuration file [APPLICATION].
\param lpKeyName - Key name in configuration file KEYNAME=.
\param lpFilename - File name and path for the configuration.
\param iDefault - Default integer return value.
\return UINT Unsigned Integer - Integer value from configuration file.
*/
UINT GetIntegerValue(LPCTSTR lpApp, LPCTSTR lpKeyName, LPCTSTR lpFilename, int iDefault)
{
UINT iResult;
iResult = GetPrivateProfileInt(lpApp,
lpKeyName,
iDefault,
lpFilename);
return iResult;
}
/*!
\brief DEFINITION : Define get boolean value from configuration file function.
DESCRIPTION : Gets an boolean value from a configuration file.
\param lpApp - Application header in configuration file [APPLICATION].
\param lpKeyName - Key name in configuration file KEYNAME=.
\param lpFilename - File name and path for the configuration.
\param lpDefault - Default boolean return value.
\return bool - Boolean value from configuration file.
*/
bool GetBoolValue(LPCTSTR lpApp, LPCTSTR lpKeyName, LPCTSTR lpFilename, LPCTSTR lpDefault)
{
string strStringValue = GetStringValue(lpApp, lpKeyName, lpFilename, lpDefault);
if(strStringValue == "TRUE")
return true;
else
return false;
}
/*!
\brief DEFINITION : Define get float value from configuration file function.
DESCRIPTION : Gets an float value from a configuration file.
\param lpApp - Application header in configuration file [APPLICATION].
\param lpKeyName - Key name in configuration file KEYNAME=.
\param lpFilename - File name and path for the configuration.
\param lpDefault - Default float return value.
\return float - Float value from configuration file.
*/
float GetFloatValue(LPCTSTR lpApp, LPCTSTR lpKeyName, LPCTSTR lpFilename, LPCTSTR lpDefault)
{
string strStringValue = GetStringValue(lpApp, lpKeyName, lpFilename, lpDefault);
return (float)strtod(strStringValue.c_str(),TEXT('\0'));
}
When compliled the stand-alone version should produce the following output to show everything is working correctly.