Allegro.cc - Online Community

Allegro.cc Forums » Programming Questions » Trying to parse a simple text file

Credits go to Physics Dave for helping out!
This thread is locked; no one can reply to it. rss feed Print
 1   2 
Trying to parse a simple text file
Ricardo Santos
Member #6,609
November 2005
avatar

Hi people

I'm getting mad trying to parse a simple text file to get a couple of vars!!
I'm tired of rewriting all the code and i still get unexpected results. Please help!

Here's the content of tiles.txt:

# Test file
############################################################
023332  egg  1  an
1  grass  1  -
28  shore  0  the
29  shore  0  the
#------------------------------------- break! :D
300  shore  0  the

The lines that are not commented have a TAB char separating the 'vars'.

Now, here's my test parser:

1#include <iostream> //cin, cout, <, >
2#include <fstream> //ifstream, ofstream
3#include <string> //string, getline()
4 
5using namespace std;
6 
7int main() {
8 ifstream file;
9 string line;
10 string name;
11 string num;
12 int passable;
13 int k,i;
14 
15 file.open("tiles.txt");
16 file.is_open();
17
18 if (file.fail())
19 return -1;
20
21 while (!file.eof()) {
22 getline(file, line);
23 
24 /* Its not a comment */
25 if (line[0] != '#') {
26 i = 0;
27 /* Tile Number */
28 while (line<i>!= '\t') {
29 i++;
30 }
31 num = line.substr(0,i);
32 k = ++i;
33 
34 /* Tile name*/
35 while (line<i>!= '\t') {
36 i++;
37 }
38 name = line.substr(k,i);
39
40 cout << "> Num: " << num <<endl;
41 cout << "> Name: "<< name <<"."<<endl;
42
43 line.substr();
44 }
45 }
46 file.close();
47 cout << "\n" <<endl;
48 system("PAUSE");
49}

And the output.. the number is ok, but everything else is messed! ???

> Num: 023332
> Name: egg     1       an.
> Num: 1
> Name: grass   1.
> Num: 28
> Name: shore   0       .
> Num: 29
> Name: shore   0       .
> Num: 300
> Name: shore   0       t.

Press any key to continue . . .

Physics Dave
Member #4,427
March 2004

line.substr(k,i-k);

Ricardo Santos
Member #6,609
November 2005
avatar

So simple, damn! ;D

Thanks a lot!

[edit]

Well i 've come into another problem.. how can i convert a std::string to int?

[/edit]

Mokkan
Member #4,355
February 2004
avatar

Perhaps try:

string myString = "15";
int myInt = atoi(myString.c_str());

:)

Indeterminatus
Member #737
November 2000
avatar

Just as an addition to the already proposed (correct) solution by Mokkan.

The following piece of code works without the use of C library functions (for the case you're interested):

1#include <string>
2#include <sstream>
3 
4// [...]
5// Somewhere in your routine:
6 
7std::stringstream str;
8std::string someString = "15";
9 
10str << someString;
11int converted;
12str >> converted;
13 
14if ( str.fail() ) {
15 // conversion didn't work!
16}

_______________________________
Indeterminatus. [Atomic Butcher]
si tacuisses, philosophus mansisses

Simon Parzer
Member #3,330
March 2003
avatar

Look here for the different methods of converterting a numeric type into a string and here for the opposite (string to number).

A J
Member #3,025
December 2002
avatar

use XML.
get a XML lib.

___________________________
The more you talk, the more AJ is right. - ML

Mika Halttunen
Member #760
November 2000
avatar

Don't.

Using XML for something as simple as that is an overkill, IMHO. :)

---------------------------------------------
.:MHGames | @mhgames_ :.

adhrymes
Member #6,567
November 2005

this is how i did something similar in a project , should be easily adapted
just keep in mind that when you write a number
1234 = 1*10^3 + 2*10^2 + 3*10^1 + 4*10^0

1int strToNum(vector<char> str)
2{
3 reverse(str.begin(),str.end());
4 double temp = 0;
5 for(int i = 0; i<str.size();i++)
6 {
7 temp += charToNum(str<i>)*pow(10,i);
8 }
9 return (int)temp;
10}
11 
12int charToNum(char cIn)
13{
14 if(cIn=='0'){return 0; }
15 else if(cIn=='1'){return 1; }
16 else if(cIn=='2'){return 2; }
17 else if(cIn=='3'){return 3; }
18 else if(cIn=='4'){return 4; }
19 else if(cIn=='5'){return 5; }
20 else if(cIn=='6'){return 6; }
21 else if(cIn=='7'){return 7; }
22 else if(cIn=='8'){return 8; }
23 else if(cIn=='9'){return 9; }
24}

BAF
Member #2,981
December 2002
avatar

Not very safe, what happens when the char function is fed something NaN? It will reach the end of a non void function, which isn't good.

Peter Hull
Member #1,136
March 2001

How about using strstream?

1ifstream in("c:\\temp\\test.txt");
2while (in)
3{
4 char buffer[1024];
5 if (in.getline(buffer, sizeof(buffer)) && (*buffer != '#'))
6 {
7 strstream inl(buffer, sizeof(buffer));
8 int c1, c2;
9 char str1[1024], str2[1024];
10 inl >> c1 >> str1 >> c2 >> str2;
11 
12 // Do something with data
13 cout << c1 << " " << str1 << " " << c2 << " " << str2 << endl;
14 }
15}

Pete

adhrymes
Member #6,567
November 2005

yea the code isn't safe cause i wrote it hastily just then, but it can be easily fixed, i just wanted to illistrate the idea. its really a simple algorithm to do str->num if you just keep in mind what i said above about how we represent numbers base b.

again we represent number base 10 so:
1847 = 1*10^3 + 8*10^2 + 4*10^1 + 7*10^0
notice here that if you reverse the string than index in the array is the same as the exponent, makes things a little easier

you can just throw another else there to deal with error checking in the charToInt func and another check in the strToInt to make sure the size is valid but as i said i just wanted to illustrate the algorithm

heres a more general algorithm:

define a counter, set to 0
reverse your string
-
for i from 0 to size of string
counter += ((int)string(i))*(10^i)
-
return counter

again this is not perfect since you can't cast the char to int directly but whatever just write a func for it (like i posted before or however you like) and include error checking (which i was too lazy to type in)

QED

BAF
Member #2,981
December 2002
avatar

And you might want to add support for floats too, which strtof has. Wouldn't be too hard though, just have it recognize '.' then change the algo after that.

Rick
Member #3,572
June 2003
avatar

Quote:

Don't.

Using XML for something as simple as that is an overkill, IMHO

I would say you either don't know much about xml or you don't like it cause it doesn't matter how simple something is xml is fast and easy. With tinyXML all you do is add 3 files to your project. No outside libraries that people have to download, plus everything is so easy. If you don't use this standard you will find yourself writing a text parser for every program/game you create, cause you will want them all in different formats. Why do that when xml will do what you want in a lot less time. That's my view on it. XML is so simple that it can never be seen as overkill.

========================================================
Actually I think I'm a tad ugly, but some women disagree, mostly Asians for some reason.

Jonatan Hedborg
Member #4,886
July 2004
avatar

Call me crazy but i like to use sscanf for these things

Thomas Fjellstrom
Member #476
June 2000
avatar

Sorry, but XML is not the panacea you think it is. Yes, for this, XML is deffinitely overkill. Does he need xml+xsl+xpath+dom+xlink+xblah+xfoo? Then he doesn't need xml.

XML has its uses, this isn't one of them.

Quote:

XML is so simple that it can never be seen as overkill.

Really? Have you read the XML spec? What you think is xml, is hardly even a fraction of what XML truly is.

--
Thomas Fjellstrom - [website] - [email] - [Allegro Wiki] - [Allegro TODO]
"If you can't think of a better solution, don't try to make a better solution." -- weapon_S
"The less evidence we have for what we believe is certain, the more violently we defend beliefs against those who don't agree" -- https://twitter.com/neiltyson/status/592870205409353730

Steve++
Member #1,816
January 2002

Quote:

What you think is xml, is hardly even a fraction of what XML truly is.

The same can be said for C++, Java, HTML, etc. but I don't see that stopping anyone. Some simple XML is useful even for the little things, such as this. That's where tinyXML is handy - it's not even a library. Chances are, if he's parsing one file in his game project, he will add even more, with different formats. Unifying them into XML-based formats would certainly be helpful.

Thomas Fjellstrom
Member #476
June 2000
avatar

Quote:

The same can be said for C++, Java

No, not really.

But heres a nice article.

--
Thomas Fjellstrom - [website] - [email] - [Allegro Wiki] - [Allegro TODO]
"If you can't think of a better solution, don't try to make a better solution." -- weapon_S
"The less evidence we have for what we believe is certain, the more violently we defend beliefs against those who don't agree" -- https://twitter.com/neiltyson/status/592870205409353730

Mika Halttunen
Member #760
November 2000
avatar

Quote:

I would say you either don't know much about xml or you don't like it cause it doesn't matter how simple something is xml is fast and easy. With tinyXML all you do is add 3 files to your project.

I'm not talking about how difficult or easy it would be to implement XML, I'm talking about the file format he's using:

# Test file
############################################################
023332  egg  1  an
1  grass  1  -
28  shore  0  the
29  shore  0  the
#------------------------------------- break! :D
300  shore  0  the

Now that is simple. Add some XML tags and it's not simple any more. Overkill for this purpose, as I said. ::)

---------------------------------------------
.:MHGames | @mhgames_ :.

Rick
Member #3,572
June 2003
avatar

Quote:

What you think is xml, is hardly even a fraction of what XML truly is.

That doesn't even matter, which is the great thing about XML. You don't have to use it to it's fullest. I think Steve++'s example about C++ is dead on. I don't have to use classes with C++. I don't have to use operator overloading if I don't need it, but I still use C++. Same can be said for XML. You're making it out to be this huge boat that is complex to use, which it doesn't have to be. Also with TinyXML things are even easier as Steve++ pointed out.

Quote:

Now that is simple. Add some XML tags and it's not simple any more. Overkill for this purpose, as I said.

Yeah the text file may look simple, but obviously he's having trouble parsing it so it's not simple to him is it? Anyway, like said above he is using this format for this program, and will probably use another format for another and be on here again in 2 months asking another parsing question. If you are doing this for learning purposes then by all means create your own parser, but if, not why reinvent the wheel. Adding < and > is going to just complicate things? Don't think so. Just my view on it. XML is a great thing that seems to be excepted by people on multiple platforms, so I think we should exploit it while it's there. It will only make it more standard to use than it already is. Which is a good thing in my mind.

Also I think ::) is the most rude smiley there is.

========================================================
Actually I think I'm a tad ugly, but some women disagree, mostly Asians for some reason.

Jonatan Hedborg
Member #4,886
July 2004
avatar

You COULD use XML, but honestly i think it would be easier to use sscanf.
I didnt look at your code, but if all you want is to store the numbers and text...
(untested code btw)

FILE *fp = fopen("file.hmm","r");
while(!feof(fp))
{
 int v1,v2;
 char text1[256],text2[256];
 int ret = fscanf(buffer,"%d %s %d %s", &v1,text1,&v2,text2);
 if( ret == 4 )
 {
  //Valid reading (ie, not a comment or something that doesent fit the pattern value text value text)
 }
}

Edited away brainfart. i think.

vpenquerch
Member #233
April 2000

How funny this is.

That reminds me of the Windows philosophy:
even if you don't need graphics stuff, windows, whatever,
the framework you use will have a window, etc, etc. You
don't have to use it though. It's just there, if you want
to.

I can't quite recall what it was, that was some API to
make libraries that could be used via a CORBA like system.
The example was a math object, that did just math stuff.
And it needed to have a (hidden) window and stuff, just
because the Windows code needed a window. How sad.

Anyway, if you want to use XML, then go for it, but please
don't try to force it down other people's throats. While
the base may be simple to use and easily extensible, I
cringe at a simple configuration file being spammed by
all these tags. Utterly unreadable.

Use Lua instead!

Er, sorry, you can ignore the previous line :)

Mika Halttunen
Member #760
November 2000
avatar

Quote:
Anyway, if you want to use XML, then go for it, but please
don't try to force it down other people's throats. While
the base may be simple to use and easily extensible, I
cringe at a simple configuration file being spammed by
all these tags. Utterly unreadable.
I second that :) XML has its uses, but I wouldn't use it for config files or other simple files, like the one this topic is about.

Now which one of the following is more readable?
This:
[graphics]
resolution = 640 x 480
bpp = 32
fullscreen = true

[sound]
sound_volume = 100
music_volume = 50
sound_enabled = true
music_enabled = true

..or maybe this?:
<?xml . . .>
<options>
  <graphics>
    <resolution>
      <value>640 x 480</value>
    </resolution>
    <bpp>
      <value>32</value>
    </bpp>
    <fullscreen>
      <value>true</value>
    </fullscreen>
  </graphics>

  <sound>
    <sound_volume>
      <value>100</value>
    </sound_volume>
    <music_volume>
      <value>50</value>
    </music_volume>
    <sound_enabled>
      <value>true</value>
    </sound_enabled>
    <music_enabled>
      <value>true</value>
    </music_enabled>
  </sound>
</options>

---------------------------------------------
.:MHGames | @mhgames_ :.

Indeterminatus
Member #737
November 2000
avatar

To defend the readability of a possible XML document a little bit, the XML output can just as well be like this:

<?xml . . .>
<options>
  <graphics>
    <resolution value="640 x 480" />
    <bpp value="32" />
    <fullscreen value="true" />
  </graphics>
</options>

Or even:

<?xml . . .>
<options>
  <graphics resolution="640 x 480" bpp="32" fullscreen="true" />
</options>

If that's useful is another question of course.

_______________________________
Indeterminatus. [Atomic Butcher]
si tacuisses, philosophus mansisses

Thomas Fjellstrom
Member #476
June 2000
avatar

Quote:

If that's useful is another question of course.

Uh, if thats readable is another question of course.

--
Thomas Fjellstrom - [website] - [email] - [Allegro Wiki] - [Allegro TODO]
"If you can't think of a better solution, don't try to make a better solution." -- weapon_S
"The less evidence we have for what we believe is certain, the more violently we defend beliefs against those who don't agree" -- https://twitter.com/neiltyson/status/592870205409353730

 1   2 


Go to: