Jump to content
  • Advertisement
Sign in to follow this  
AntonioR

Reading from a text file (c++)

This topic is 2609 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, I need some help.

I want to be able to write some variable values in a text file and then read it from inside the application.

1.
Text file example :

window=0
screenwidth=800
screenheight=600
app_title=my project


So i want to read "window" and then its value, and then apply that value to appropriate variable inside the code.
Also I want to be able to read string or char values.

2.
I would also want to put more variables in the same row, and the read it one by one:
1 0 day month 1000 500

Share this post


Link to post
Share on other sites
Advertisement
So which bit are you having a problem with? Reading from a file? Splitting it at the =? Determining whether it's a string or a char?

No-one here is going to just do it for you.

But as a start look into strings, iostream, and data structures.

Share this post


Link to post
Share on other sites
Actually I wouldn't go that route (manually parsing using streams) for a configuration file. Find an existing configuration file library with a syntax that you like and just use that. INI files are strangely popular and so are XML files. There's also boost::program_options for a possibility.

Share this post


Link to post
Share on other sites
For a quick and easy bit of string manipulation if you have access to boost I'd recommend looking at boost::split (within boost/algorithm/string.hpp).

Share this post


Link to post
Share on other sites
I just need it for some simple stuff, I don't want to use a whole new library for that.

I know something about iostream, I can read numbers like this.


ifstream filein("config.txt");
filein >> fullscreen >> SCREENW >> SCREENH ;


But the text file has just numbers inside so it won't be readable if I add some new stuff.

1
1024
768


So I guess
Splitting it at the =? Determining whether it's a string or a char?[/quote] is the actual problem.

Share this post


Link to post
Share on other sites
If you are going to do it that way (roll your own), I think the basic process is:

1) read the line
2) find offset of '='
3) read before the '=' into a token variable
4) read behind the'=' into a value variable
5) switch on the token to assign the value variable to the correct program variable.
6) repeat with next line

Share this post


Link to post
Share on other sites
I managed to find some code example, it works:

bool LoadSettings(int *Width, int *Height, int *Fullscreen)
{
FILE* fp;

char string[500];
fp = fopen("config.txt","r");

if (fp!=NULL)
{
char item[300];
char value[300];

while (fgets (string , 300 , fp)!=NULL)
{
//sscanf(string,"%s %[^\n]",&item, &value);
sscanf(string,"%s %s",&item, &value);

if (strcmp(item, "width")==0)
{
*Width = atoi(value);
}
else if (strcmp(item, "height")==0)
{
*Height = atoi(value);
}
else if (strcmp(item, "fullscreen")==0)
{
*Fullscreen = atoi(value);
}
}
}
else
{
return false;
}

}


Txt file:

width 1024
height 768
fullscreen 0

Share this post


Link to post
Share on other sites
well, you could simply use

while (fgets (string , 300 , fp)!=NULL)
{
sscanf(string,"width %d",Width);
sscanf(string,"height %d",Height);
sscanf(string,"fullscreen %d",Fullscreen);
}


If the string is not matching, the variables won't be affected, so it can be simple as that. You can even check the return value of sscanf (look it up)

But that's C, not C++. I'm sure C++ has better methods

Share this post


Link to post
Share on other sites
Here is what I have been using for awhile, it doesn't read everything at once, but you can continually check the file for various settings.
Feel free to use it or make one yourself based on this, Its a modified version from some tutorial I read about 5 years ago, sorry but I do not have the link :/

ReadConfig.h

//Read a specific variable from our config file and return its value
//This is our error logging class
#ifndef READCONFIG_OBJECT

#define READCONFIG_OBJECT

#include <winsock.h>
#include <stdio.h>
#include <io.h>
#include <FCNTL.H>
#include <iostream>
#include <fstream>
#include <string>
#include <list>
using namespace std;

#define MAX_STRING 255



int ReadConfigInt(char* Filename,char* Variable); //return -1 on fail, -2 on file not found
string ReadConfigString(const char* Filename,char* Variable); //returns NULL on failure

#endif


ReadConfig.cpp

//Read config
#include "stdafx.h"
#include "ReadConfig.h"

int ReadConfigInt(char* Filename,char* Variable)
{


char line[MAX_STRING];
memset(line,0,MAX_STRING);
ifstream myconfig(Filename);
if(!myconfig)//could not open file
{
return NULL; //-2 file not found
}

while(!myconfig.eof())
{

myconfig.getline(line, MAX_STRING); // delim defaults to '\n'
if(myconfig)
{
if(line[0] == '/') //we are skipping this line
{ // skip comment line
continue;
}
else
{


char *pointerchar = NULL;
char var[MAX_STRING] = {'\0'}; // variable name
char val[MAX_STRING] = {'\0'}; // value its set to
size_t length =0;
pointerchar = strchr(line, '\n'); // find our newline
if(pointerchar != NULL)
{
*pointerchar = '\0'; //change newline to null character
}
length = strlen(line);
pointerchar = strchr(line, '='); //find our equals character
if(pointerchar == NULL)
{
return NULL; //failure
} //Parse Error

memcpy(var, line, pointerchar - line);// get the part before the first =
pointerchar++;// skip the actual '=' sign
memcpy(val, pointerchar, (line+length)-pointerchar);// get the value of the var
if (strcmp(var,Variable)==0)//see if we found it
{
return atoi(val);
}
}

}

}

myconfig.close();


return NULL; //didnt find that variable
}



string ReadConfigString(const char* Filename,char* Variable)
{


char line[MAX_STRING];
memset(line,0,MAX_STRING);
ifstream myconfig(Filename);
if(!myconfig)//could not open file
{
return "Unknown";
}

while(!myconfig.eof())
{

myconfig.getline(line, MAX_STRING); // delim defaults to '\n'
if(myconfig)
{
if(line[0] == '/') //we are skipping this line
{ // skip comment line
continue;
}
else
{


char *pointerchar = NULL;
char var[MAX_STRING] = {'\0'}; // variable name
char val[MAX_STRING] = {'\0'}; // value its set to
size_t length =0;
pointerchar = strchr(line, '\n'); // find our newline
if(pointerchar != NULL)
{
*pointerchar = '\0'; //change newline to null character
}
length = strlen(line);
pointerchar = strchr(line, '='); //find our equals character
if(pointerchar == NULL)
{
return NULL;
} //Parse Error

memcpy(var, line, pointerchar - line);// get the part before the first =
pointerchar++;// skip the actual '=' sign
memcpy(val, pointerchar, (line+length)-pointerchar);// get the value of the var
if (strcmp(var,Variable)==0)//see if we found it
{
return val;
}
}

}

}

myconfig.close();


return NULL; //didnt find that variable
}

Share this post


Link to post
Share on other sites
Doing the same in c++:

#include <string>
#include <fstream>

bool LoadSettings(int &Width, int &Height, int &Fullscreen)
{
std::ifstream file("config.txt");
if(!file.is_open())
{
return false;
}
std::string line;
while(std::getline(file, line))
{
std::stringstream stream(line);
std::string name;
int value;
if(stream >> name >> value)
{
if(name == "width")
{
Width = value;
}
else if(name == "height")
{
Height = value;
}
else if(name == "fullscreen")
{
Fullscreen = value;
}
else
{
std::cerr << "Unknown config name: " << name << '\n';
}
}
else
{
std::cerr << "Failed to parse line: " << line << '\n';
}
}
}

Note this also features more robust error checking. The code you posted fails to fclose() the file you fopen(), among other issues.

I would not recommend using yewbie's code, it is terrible.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!