Sign in to follow this  

ifstream, what stream?

This topic is 4278 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi, all, me again (no, don't hide...[grin]) I'm having trouble geeting my program to run. It's (eventually) going to be an isometric game engine, but I seem to be having trouble with my .ini file loading function. I know it's this, because the code loads and displays a window fine, until I add my function call to the mix. The idea is that the function reads an .ini file, and stores the data in a struct. This data includes a path to my graphics, screen resolution, boolean variable for fullscreen/windowed modes, and a few other bits and bobs. The program compiles and links fine, but when I come to run it, I don't even get a chance to blink before it closes itself down. As always, I'm using the Code::Blocks ver1.0 RC2 IDE with MinGW compiler. Now for the code:
misc.h:
#ifndef MISC_
#define MISC_
#include <string>
#include <vector>
using namespace std;
typedef struct {
    public:
     string inistyle;                   //.ini style
     string graphics_path;              // path to game graphics
     string tileset_list;               // path to list of tilesets
     bool fullscreen;                   // fullsceen value
     long int xres;
     long int yres;
 } INI_FILESTYPE;                        // the effective "config" file struct

typedef struct {
    public:
     string inistyle;                   // .ini style
     long int numsets;                  // number of tilesets
     vector<string> tilesets;           // names of each tileset
 } INI_TOTALTILESTYPE;                   // the struct that holds the names of
                                        // all the tilesets for loading

typedef struct {
    public:
    string inistyle;                    // .ini style
    string basepath;                    // path from current to tileset
    string eventpath;                   // path to event graphics
    long int num_tiles;                 // number of tiles in set
    vector<string> tilenames;           // filenames of each tile
} INI_TILESTYPE;                         // the tileset struct for loading tiles

INI_FILESTYPE ReadConfig(char* filename);
//INI_TOTALTILESTYPE ReadTotTiles(string filename);
//INI_TILESTYPE ReadTileset(string filename);


#endif

main.cpp, ReadConfig() function
INI_FILESTYPE ReadConfig(char* filename)
{
    ifstream infile(filename);
    string style,arg,cmd;
    INI_FILESTYPE files;

    infile >> style;

    if(style != "inistyle=")
    {
        MessageBox(NULL,"Error in .INI file. file should start with 'inistyle= '","Error!",MB_OK);
    }
    else
        infile >> style;
    if(style == "files")
    {
        files.inistyle = style;
        bool found_gpath=false;
        bool found_tilesets=false;
        bool found_xres=false;
        bool found_yres=false;
        bool found_fullscreen=false;
        bool done=false;
        while(!done)
        {
            if(infile.eof()==true)
                break;
            else
            {
                infile >> cmd;
                if(cmd == "graphics=" && found_gpath == false)
                {
                    infile >> files.graphics_path;
                    found_gpath=true;
                }
                else if(cmd == "tilesetlist=" && found_tilesets == false)
                {
                    infile >> files.tileset_list;
                    found_tilesets=true;
                }
                else if(cmd == "fullscreen=" && found_fullscreen == false)
                {
                    infile >> files.fullscreen;
                    found_fullscreen=true;
                }
                else if(cmd == "xres=" && found_xres == false)
                {
                    infile >> files.xres;
                    found_xres=true;
                }
                else if(cmd == "yres=" && found_yres == false)
                {
                    infile >> files.yres;
                    found_yres=true;
                }
            }
        }
    }
}

I know it's something to do with this function, because I've taken out all uses of the returned struct, so it just runs the function, before setting up the window. Any Help would be appreciated.

Share this post


Link to post
Share on other sites
Any reason not to use GetPrivateProfileString / Int?

P.S.
MSDN says:
Quote:

Applications should store initialization information in the registry.

Also, maybe look into XML.

[Edited by - raz0r on March 26, 2006 8:53:22 PM]

Share this post


Link to post
Share on other sites
This is my first attempt at parsing a text file in Cpp.
I shouldnt have thought there was any major performance difference between XML and .ini files, and I haven't got a clue what you're talking about with the "GetPrivateProfileString / Int" part

Share this post


Link to post
Share on other sites

char szBuffer[256] = {char()};
int iBuffer = int();

GetPrivateProfileString("group", "dummy_a", "default", szBuffer, sizeof(szBuffer), "Dummy.ini"); //"abc" or "default"
iBuffer = GetPrivateProfileInt("group", "dummy_b", int(), "Dummy.ini"); //123 or 0

//Also, check for failiure




Dummy.ini:

[group]
dummy_a = abc
dummy_b = 123





[Edited by - raz0r on March 26, 2006 8:28:11 PM]

Share this post


Link to post
Share on other sites
You know, file I/O can fail. It might behoove you to check for success after an I/O operation.

First things first, did the stream open?

ifstream infile(filename);
if (!ifstream)
{
// display an error about the file not opening....
}

Take it from there.

Share this post


Link to post
Share on other sites
OK, this is what I tried out, and I keep getting the same problemm(ie, compile fine, but get an error when I try to run it).

I know I didn't get the whole file read like in my first post, but I wanted to make sure I got this right before hand;

main.cpp ReadConfig()


INI_FILESTYPE ReadConfig(char* filename)
{
char *buf[1024];
int ibuf;
INI_FILESTYPE file;
ifstream infile(filename);
if(!infile)
{
MessageBox(NULL,"Unable to open .ini file.","Error!",MB_OK);
}
else
{
GetPrivateProfileString("files","graphics","/graphics/",*buf,sizeof(*buf),"files.ini");
}
//file.graphics_path = *buf;
return file;
}






The reason for the commented line was to see if it was that causing the error (it wasn't)

Any idea on what I'm doing wrong?

[Edited by - webwraith on March 29, 2006 5:06:50 AM]

Share this post


Link to post
Share on other sites
char *buf[1024] is creating an array of 1024 pointers to char, not a 1024 char array. Do you mean char buf[1024]? Don't know much about GetPrivateProfileString but looks like it wants a pointer to an array.

Share this post


Link to post
Share on other sites
Also, as I say, I don't know anything about GetPrivateProfileString but if you are using the ifstream to test that the file opens okay, you should probably close it again before you call GetPrivateProfileString as I assume it must open the file itself internally.

Could you not just call GetPrivateProfileString on its own? I assume it returns an error if the file can't be opened.

Share this post


Link to post
Share on other sites
If your ini is going to get anything more complex than VERY basic settings, you may want to consider XML. The ini syntax gets very messy if items are not completely indepent of one another. The easiest way to read an ini is, as mentioned, the GetPrivateProfileString type functions. The syntax of these parameters gets a bit ugly imo, mixing c-style strings with c++ strings, paths, etc. XML packages written in C++ (Tiny-XML) make the process much less painful.

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
Quote:
Original post by Bregma
You know, file I/O can fail. It might behoove you to check for success after an I/O operation.

First things first, did the stream open?

ifstream infile(filename);
if (!ifstream)
{
// display an error about the file not opening....
}

Take it from there.


Umm isn't that suppose to be....

ifstream infile(filename);
if (!infile.is_open()) {
.....
}

Share this post


Link to post
Share on other sites
i'd like to mention that

infile >> style;

using the >> is bad when reading files, it doesn't pickup ' ' white spaces, or actually stop reading when it his a white space!! Or maybe it was just 1 char at a time in a file that >> will get skipping over white spaces.. anyhow..

Just want to keep that in mind, getline() is much better pratice.

Share this post


Link to post
Share on other sites
I'd like to note that using GetPrivateProfileString (a windows API function) is generally a bad idea because they are _HORRIBLY_ slow. As an example, I made a program that does 3 things:
(1) Load Data from INI (~60 values)
(2) Process the data
(3) Copy ~15 files averaging around 15kb each

Of the three, most of the program's run time was the series of calls to GetPrivateProfileString. I created my own INI class that parsed the data manually, and the execution time went from about 10 seconds to ~2 with the file copying taking the majority of the runtime.

It probably won't actually matter, since you don't load an INI repeatedly, but in my case it made a difference.
I can only guess that the 'problem' is that the windows INI functions don't maintain state between calls so it must repeatedly parse the same file AND it was done in an inefficient way, but it's still far slower than it should be.

I can't post the code for the class because I did it as part of a project for work. Just remeber that the STL is your friend =-)
std::getline(TheFile, Line);
CommentOffset = Line.find_first_of(';');
SectionOffset = Line.find_first_of('[');
ValueOffset = Line.find_first_of('=');

Share this post


Link to post
Share on other sites

This topic is 4278 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this