Server Help

Non-Subspace Related Coding - make c++ read from ini files

hellzlaker - Mon Apr 07, 2008 7:08 pm
Post subject: make c++ read from ini files
any one know any good tutorials on how to make c++ read from ini files for begginers? and doesnt even have to be ini files anything where a variable can be read from file like

x=5
name=john
game= continuum

so that c++ would read from file and input variables put..
CypherJF - Mon Apr 07, 2008 8:41 pm
Post subject:
Does this help? Not sure if it's correct, or where I got it from.

Code: Show/Hide

   //
   String getIni(String section, String key, String fname);
   void writeIni(String section, String key, String value, String fname);
   //


Code: Show/Hide

#include "spawn.h"

#pragma once
#define WIN32_LEAN_AND_MEAN
#include <windows.h>

const int BUFFER_LEN = 256;
static char buffer[BUFFER_LEN];
static char path[BUFFER_LEN];

String botInfo::getIni(String section, String key, String fname)
{
   GetCurrentDirectory(BUFFER_LEN - 64, path);
   strcat(path, fname);
   GetPrivateProfileString(section, key, '\0', buffer, BUFFER_LEN, path);
    return (String)buffer;
}

void botInfo::writeIni(String section, String key, String value, String fname)
{
   GetCurrentDirectory(BUFFER_LEN - 64, path);
   strcat(path, fname);
   WritePrivateProfileString(section, key, value, path);
}

hellzlaker - Mon Apr 07, 2008 9:04 pm
Post subject:
hm is there a simpler explanation? and it doesnt have to deal with mervbots, like for a random program ?
Bak - Mon Apr 07, 2008 9:06 pm
Post subject:
http://wiki.minegoboom.com/index.php/MERVBot_Tutorial#Input.2FOutput_to_files
hellzlaker - Tue Apr 08, 2008 4:18 pm
Post subject:
I think that tutorial for ini files is only with MervBots since when i tried it, it didnt compile and compiler said that CMPSTART' was undeclared

here is source:
Code: Show/Hide

#include "stdlib.h"    // for atoi()
#include <windows.h>   // for GetPrivateProfileString()
#include <iostream>
#include <fstream>
using namespace std;

void p()
{
     system("pause");
}

int main()
{
    ifstream conf;
    conf.open("conf.txt");
    if (!conf)
    {
              cout<<"\n\n\n\t\t\tFile conf.txt doesn't exist!\n\n\t\t\t";
              p();
              return 0;
    }
   
    char line[256];
   
    while (conf.getline(line, 256))
    {
          if (CMPSTART("player=", line))
          {
                                  int player_age = atoi(&(line[7]));
          } 
    }
}


here are errors
Code: Show/Hide
Compiler: Default compiler
Executing  g++.exe...
g++.exe "C:\Documents and Settings\Owner\Desktop\Programing\c++\ini file reader\inifilereader.cpp" -o "C:\Documents and Settings\Owner\Desktop\Programing\c++\ini file reader\inifilereader.exe"    -I"C:\Dev-Cpp\lib\gcc\mingw32\3.4.2\include"  -I"C:\Dev-Cpp\include\c++\3.4.2\backward"  -I"C:\Dev-Cpp\include\c++\3.4.2\mingw32"  -I"C:\Dev-Cpp\include\c++\3.4.2"  -I"C:\Dev-Cpp\include"   -L"C:\Dev-Cpp\lib"
C:\Documents and Settings\Owner\Desktop\Programing\c++\ini file reader\inifilereader.cpp: In function `int main()':
C:\Documents and Settings\Owner\Desktop\Programing\c++\ini file reader\inifilereader.cpp:27: error: `CMPSTART' undeclared (first use this function)
C:\Documents and Settings\Owner\Desktop\Programing\c++\ini file reader\inifilereader.cpp:27: error: (Each undeclared identifier is reported only once for each function it appears in.)

Execution terminated

k0zy - Tue Apr 08, 2008 4:45 pm
Post subject:
I guess it doesn't work because CMPSTART is some mervbot macro.

Try strncmp instead.
http://www.cplusplus.com/reference/clibrary/cstring/strncmp.html
Doc Flabby - Tue Apr 08, 2008 4:48 pm
Post subject:
http://code.jellycan.com/simpleini/

or read up in the windows api Got a complete example in this link
http://msdn2.microsoft.com/en-us/library/ms725501(VS.85).aspx
Samapico - Tue Apr 08, 2008 5:04 pm
Post subject:
I made myself some functions using windows APIs, from other plugins:

Code: Show/Hide

String readINIkeyString(char *section, char *key, char *_default, char *path);
String readINIkeyLongString(char *section, char *key, char *_default, char *path);
int      readINIkeyInt(char *section, char *key, int _default, char *path);




String readINIkeyString(char *section, char *key, char *_default, char *path)
{
   char resultbuffer[64];
   GetPrivateProfileStringA(section, key, _default, resultbuffer, 64, path);
   resultbuffer[63] = '\0';

   return (String) resultbuffer;
}
String readINIkeyLongString(char *section, char *key, char *_default, char *path)
{
   char resultbuffer[256];
   GetPrivateProfileStringA(section, key, _default, resultbuffer, 256, path);
   resultbuffer[255] = '\0';

   return (String) resultbuffer;
}
int readINIkeyInt(char *section, char *key, int _default, char *path)
{
   return (int)GetPrivateProfileIntA(section, key, _default, path);
}


You need <winbase.h> included, but if you put these things in spawn.h and spawn.cpp, it should already be included
hellzlaker - Tue Apr 08, 2008 7:26 pm
Post subject:
ok i tried this and forsome reason all values return with the default not whats in the file

file
Code: Show/Hide

[Names]
player=hellzlaker
zone=Counter Strike E

[Ages]
player=15
zone=4


source
Code: Show/Hide

#include <stdlib.h>    // for atoi()
#include <windows.h>   // for GetPrivateProfileString()
#include <iostream>
#include <fstream>
#include <winbase.h>
#include <string>
using namespace std;

void p()
{
     system("pause");
}

string readINIkeyString(char *section, char *key, char *_default, char *path)
{
   char resultbuffer[64];
   GetPrivateProfileStringA(section, key, _default, resultbuffer, 64, path);
   resultbuffer[63] = '\0';

   return (string) resultbuffer;
}

string readINIkeyLongString(char *section, char *key, char *_default, char *path)
{
   char resultbuffer[256];
   GetPrivateProfileStringA(section, key, _default, resultbuffer, 256, path);
   resultbuffer[255] = '\0';

   return (string) resultbuffer;
}

int readINIkeyInt(char *section, char *key, int _default, char *path)
{
   return (int)GetPrivateProfileIntA(section, key, _default, path);
}

int main()
{
   
   
   
   
   
    string playername=readINIkeyString("Names","player","error","conf.txt");
    string zonename=readINIkeyString("Names","zone","error","conf.txt");
    int playerage=readINIkeyInt("Ages","player",0,"conf.txt");
    int zoneage=readINIkeyInt("Ages","zone",0,"conf.txt");
   
    cout<<"\n\tPlayer name  : "<<playername;
    cout<<"\n\tPlayer age   : "<<playerage;
    cout<<"\n\tZone name    : "<<zonename;
    cout<<"\n\tZone age     : "<<zoneage<<"\n\n\t\t";
   
    p();
   
    return 0;
}
   
   

Bak - Tue Apr 08, 2008 9:18 pm
Post subject:
replace
Code: Show/Hide
if (CMPSTART("player=", line))

with
Code: Show/Hide
if (strstr(line,"player=") == line)


and #include "string.h"
Samapico - Tue Apr 08, 2008 11:32 pm
Post subject:
string playername=readINIkeyString("Names","player","error","conf.txt");

hmmm... yeah for some reason, I remember I had to give it absolute paths... Like "C:\blahblah\conf.txt" instead of just "conf.txt". For this I had a function that returns the current directory of the exe or dll.

Code: Show/Hide
String CurrentDirectory()
{
   char path[520];
   GetCurrentDirectoryA(520, path);
   strcat(path, "\\");
   return (String) path;
}


Code: Show/Hide
string path = CurrentDirectory() + "conf.ini";
string playername=readINIkeyString("Names","player","error",path);


should work... All my code was using 'String', not 'string' though, so I don't know if there are any typecasting differences between them...
hellzlaker - Wed Apr 09, 2008 5:48 pm
Post subject:
thanks it worked, and I used (string) instead of (String) since Dev c++ told me (String) is undeclared...
Samapico - Thu Apr 10, 2008 11:54 am
Post subject:
well, String is declared in the mervbot core somewhere. If you use it in spawn.cpp, spawn.h, or command.cpp, it will be declared
Bak - Thu Apr 10, 2008 8:51 pm
Post subject:
it's usually frowned upon to return structures or classes (like string or String) or pass them into functions as parameters (because it copies them implicitly).
Samapico - Fri Apr 11, 2008 1:52 am
Post subject:
hmm, good point I guess... I could improve that tongue.gif
hellzlaker - Wed Apr 16, 2008 8:43 pm
Post subject:
samapico your functions worked in my stand alones exes but when i tried to use then in merv i had a bit confusion, like where to declare variables for an example i tried this
Code: Show/Hide

         String PointsName1 = readINIkeyString("conf","PointsName1","points",CurrentDirectory()+"DCmissions.ini");
         

         else if (c->check(PointsName1) )
         {
            int money = p->score.killPoints+p->score.flagPoints;
            sendPrivate(p,(String)p->name+", you have "+(String)money );


the compile errors were
Code: Show/Hide
1>------ Build started: Project: default, Configuration: Debug Win32 ------
1>Compiling...
1>command.cpp
1>c:\documents and settings\owner\desktop\programing\c++\dc missons\dcmissions\command.cpp(203) : error C2181: illegal else without matching if
1>Build log was saved at "file://c:\Documents and Settings\Owner\Desktop\Programing\c++\DC missons\DCmissions\Debug\BuildLog.htm"
1>default - 1 error(s), 0 warning(s)
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========


i think compiler messed up since when i remove the String PlayerName = etc.. if compiles fine, i tried moving the String PlayerName = .. before the if, but some other wierd error came up

and i have declared the function in spawn.h and spawn.cpp
hellzlaker - Mon Jul 21, 2008 11:50 am
Post subject:
sorry old topic but i reformatted computer and lost all the info that i had and i got this to work last time but now i get this error for some reason

Code: Show/Hide
C:\Documents and Settings\Owner\Desktop\programing\tests\Untitled1.cpp:61: error: cannot convert `std::string' to `char*' for argument `4' to `std::string readINIkeyString(char*, char*, char*, char*)'

C:\Documents and Settings\Owner\Desktop\programing\tests\Untitled1.cpp:62: error: cannot convert `std::string' to `char*' for argument `4' to `int readINIkeyInt(char*, char*, int, char*)'


This is the code
Code: Show/Hide
#include <windows.h>
#include <iostream>
#include <stdlib.h>


using namespace std;

void visual()
{
     SetConsoleTitle("TEST");
     system("color f0");     
     system("cls");
}

void c()
{
     system("cls");
}

string CurrentDirectory()
{
   char path[520];
   GetCurrentDirectoryA(520, path);
   strcat(path, "\\");
   return (string)path;
}

string readINIkeyString(char *section, char *key, char *_default, char *path)
{
   char resultbuffer[64];
   GetPrivateProfileStringA(section, key, _default, resultbuffer, 64, path);
   resultbuffer[63] = '\0';

   return (string) resultbuffer;
}

string readINIkeyLongString(char *section, char *key, char *_default, char *path)
{
   char resultbuffer[256];
   GetPrivateProfileStringA(section, key, _default, resultbuffer, 256, path);
   resultbuffer[255] = '\0';

   return (string) resultbuffer;
}

int readINIkeyInt(char *section, char *key, int _default, char *path)
{
   return (int)GetPrivateProfileIntA(section, key, _default, path);
}


     
int main()
{     
    visual();
    system("pause");
    c();
   
    string path = CurrentDirectory()+"test.ini";
     
    string port = readINIkeyString("main","port","ERROR CAN'T READ!",path);
    int intport = readINIkeyInt("main","port",-99999,path);
   
    cout<<"\n\n\tString Port\t"<<port<<"\n\tInt Port\t"<<intport<<"\n\n\n\n\n\t\t";
    system("pause");
   
    return 0;
}



I tried converting string to char but still didn't work...
Cheese - Mon Jul 21, 2008 1:42 pm
Post subject:
how do u put a [directory] ip= type thing in there?
where it reads a string with an unknown # of name,name2,etc?
Samapico - Mon Jul 21, 2008 10:55 pm
Post subject:
2 ways:

Code: Show/Hide
[section]
Something1=stuff
Something2=blah
Something3=oink


You keep reading from the ini by incrementing a variable until it returns you "" (or whatever the default value is)


Or:
Code: Show/Hide
[section]
Something=stuff;blah;oink


Use whatever separator you want, and use the split function of the string. (Mervbot's String class has it; there must be something similar with the standard string class, or you can go in merv's code and take the split function to make your own) Basically it will take a substring up to a specified character and return you the left part, while removing that part from the string itself. So you keep doing this until your string is empty.
Example:
Code: Show/Hide
String somestring="stuff;blah;oink";
do
{
    String somepart = somestring.split(';');

    //somepart would be "stuff" the first time, then "blah", then "oink", then ""
} while (!somestring.isEmpty());

Purge - Mon Jul 21, 2008 11:03 pm
Post subject:
Using WinAPI would be much easier in your case. Check MSDN for the GetPrivateProfileString() function.
All times are -5 GMT
View topic
Powered by phpBB 2.0 .0.11 © 2001 phpBB Group