Hey.
I'm trying to make a C++ program that will read a .INI file and process it into three parts. Headers, variables, and values.
Here's the INIReader.h file
Code:
#ifndef INIREADER_H
#define INIREADER_H
#include <iostream>
#include <vector>
#include <math.h>
using namespace std;
struct headNode
{
char header[255];
vector<char*> variables;
vector<char*> values;
};
class CINIReader
{
//member variables
public:
char m_filename[255];
vector<headNode> headers;
//member functions
public:
CINIReader(); //constructor
~CINIReader(); //destructor
bool SetFile ( char file[] );
bool ParseFile ( char file[] );
int GetInt ( char varname[], char header[] );
char GetStr ( char varname[], char header[] );
bool GetBool ( char varname[], char header[] );
int CharToInt ( char var[] );
private:
bool StripTags ( const char *source, size_t bytes, char *result );
bool SplitString ( const char *source, size_t bytes, const char delim, char * variable, char *value );
};
#endif
Here's the INIReader.cpp file
Code:
#include "INIReader.h"
#include <fstream>
CINIReader::CINIReader()
{
}
CINIReader::~CINIReader()
{
}
//member functions
bool CINIReader::SetFile ( char file[255] )
{
strcpy_s ( m_filename, 255, file );
return ParseFile ( file );
}
bool CINIReader::ParseFile ( char file[] )
{
ifstream in ( file );
if ( !in.is_open() )
return false;
char buffer[255];
char buffer2[255];
char buffer3[255];
bool alreadyOne = false;
headNode *hn;
while ( in.good() )
{
in.getline ( buffer, 255 );
switch ( buffer[0] )
{
//start of a new header
case '[':
if ( alreadyOne )
{
headers.push_back ( *hn );
delete hn;
}
hn = new headNode;
StripTags ( buffer, 255, hn->header );
alreadyOne = true;
break;
//all comments...
case ';':
case NULL:
case ' ':
case '#':
break;
//add a line for the variables
default:
SplitString ( buffer, 255, '=', buffer2, buffer3 );
hn->variables.push_back ( buffer2 );
hn->values.push_back ( buffer3 );
break;
}
}
if ( alreadyOne )
{
headers.push_back ( *hn );
delete hn;
}
return true;
}
bool CINIReader::SplitString ( const char *source, size_t bytes, const char delim, char *variable, char *value )
{
const char *s = source;
char *var = variable;
char *val = value;
bool afterEqualSign = false;
size_t b = 0;
//go through the entire source string
for ( size_t i = 0; i < strlen ( source ); i++ )
{
//break if necessary for security reasons (buffer overflow)
if ( b >= bytes )
{
return false;
}
if ( s[i] == delim )
{
afterEqualSign = true;
}
else if ( afterEqualSign && s[i] != '=' )
{
*val = s[i];
val++;
}
else if ( !afterEqualSign )
{
*var = s[i];
var++;
}
b++;
}
//end of strings
*val = '\0';
*var = '\0';
return true;
}
//strips the [ and ] from a header. for example [test] would become test.
bool CINIReader::StripTags ( const char *source, size_t bytes, char *result )
{
const char *s;
char *r;
size_t b = 0;
s = source;
r = result;
int i = 1;
while ( s[i] != ']' )
{
if ( b >= bytes )
return false;
*r = s[i++];
r++;
b++;
}
*r = '\0';
return true;
}
//converts ascii strings to integers (i wanted to see if I could do it :D)
int CINIReader::CharToInt ( char str[] )
{
size_t stringSize = strlen ( str );
int num = 0;
int buffer;
for ( size_t i = 0; i < stringSize; i++ )
{
buffer = static_cast<int>(str[i]);
buffer = buffer - 48;
num += buffer * (int)pow ( (double)10, (double)( ( stringSize - 1 ) - i ) );
}
return num;
}
Here's the main.cpp file
Code:
#include <iostream>
#include "INIReader.h"
#include <vector>
using namespace std;
void print ( const char *c )
{
const char *p;
for ( p = c; *p != '\0'; p++ )
{
cout << *p;
}
}
int main ( void )
{
CINIReader read;
read.SetFile ( "test.txt" );
for ( int i = 0; i < read.headers.size(); i++ )
{
print ( read.headers.at(i).header );
for ( int j = 0; j < read.headers.at(i).variables.size(); j++ )
{
cout << "variable: ";
print ( read.headers.at(i).variables.at(j) );
cout << " Value: ";
print ( read.headers.at(i).values.at(j) );
cout << endl;
}
cout << endl;
}
system("pause");
return 0;
}
Here's the test.txt file (acts as an INI file, just with a diff ext)
Code:
[head 1]
var1=this is a variable
var2=hopefully this will work
var3=nope. its not...
;this is a comment, it will be ignored by the program
#this is a comment, it will be ignored by the program
[head2]
variable=3
Here's my output:
Code:
head 1variable: ╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠
╠╠╠╠╠╠╠╠⌠√↨ Value:
variable: ╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠
╠╠⌠√↨ Value: ►²↨
variable: ╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠
╠╠⌠√↨ Value: ►²↨
head2variable: ╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠
╠╠╠╠╠╠╠⌠√↨ Value: ►²↨
Press any key to continue . . .
Any reason why the variable and value are complete garbage?
Thanks in advance,
Guitarist809