Sorry your browser is not supported!

You are using an outdated browser that does not support modern web technologies, in order to use this site please update to a new browser.

Browsers supported include Chrome, FireFox, Safari, Opera, Internet Explorer 10+ or Microsoft Edge.

AppGameKit Classic Chat / I can't read integer from files

Author
Message
Luca91
11
Years of Service
User Offline
Joined: 1st Sep 2012
Location: Italy
Posted: 16th Nov 2012 23:31
Hello guys ,

I need to read some integer values from a file ( Documents/AGK/Map/MyMap.txt )

but this code seems to fail:



my MyMap.txt files contain one integer value (5), and it is 1kb.

What's the problem ?
Marl
12
Years of Service
User Offline
Joined: 19th Nov 2011
Location: Bradford, UK
Posted: 17th Nov 2012 00:36
try this


I never use readInteger, reading a string and converting allows you to add data validation and prevents errors if a non-integer is read.

Although AppGameKit is pretty good at dodging these kinds of errors, it's still good practice to have a layer of protection of your own.
xCept
21
Years of Service
User Offline
Joined: 15th Dec 2002
Location:
Posted: 17th Nov 2012 00:41
Assuming that GetFileExists("MyMap.txt") is returning 1 (to rule out the possibility of an incorrect folder mapping), what value is assigned to SF when you read it?

Keep in mind that AppGameKit looks for null terminated values when reading in specific data types (ReadString, ReadInteger, etc). If you simply save the values out in Notepad they probably won't be null terminated so reading in values in this way will probably cause issues. Marl's suggestion is good, using the more general ReadLine to read each individual line and parse it as needed.
Auger
12
Years of Service
User Offline
Joined: 21st Aug 2011
Location: Out There
Posted: 17th Nov 2012 00:53
By value 5 do you mean binary 5? ReadInteger reads in binary values not strings. So you'd have to write the integers out first to file with WriteInteger() or else use a hexeditor to put your values in the file.

If you want to use strings then Marl's code is the way to go.

Auger
Marl
12
Years of Service
User Offline
Joined: 19th Nov 2011
Location: Bradford, UK
Posted: 17th Nov 2012 01:01
Quote: "ReadInteger reads in binary values not strings."

I'd never even considered that, well spotted.

So for the same reason, writing strings is a good idea so that you can check the contents in notepad
Luca91
11
Years of Service
User Offline
Joined: 1st Sep 2012
Location: Italy
Posted: 17th Nov 2012 01:01
Yeha Marl's solution works !!

But what about if I have a txt file that looks like this:



I've written this code , but it doesn't work :



Any help pls ? thanks
xCept
21
Years of Service
User Offline
Joined: 15th Dec 2002
Location:
Posted: 17th Nov 2012 01:06
ReadLine does just that, it reads entire lines at a time.

So, the first call to ReadLine(1) will return a string of: 1 1 0 0 2 1 0 2

You can split each line into individual components after reading it by using commands such as GetStringToken with space as the delimiter (look in manual for specific usage).
Marl
12
Years of Service
User Offline
Joined: 19th Nov 2011
Location: Bradford, UK
Posted: 17th Nov 2012 01:30 Edited at: 17th Nov 2012 01:35
Try not to use hard coded values for your loops, if the file doesn't match you might get problems, and if you change the data, you may have to modify your code.

Firstly - offload the file handling to a function so you don't have to repeat it.

So the new condition looks like this;

(There is no point having a function to close the file as it is only one line anyway.)

Now the bit that goes where the ... is.

This reads each line, counts the number of space delimited integers and splits the read value into those parts.

NB: this uses array indexes starting at 1 to keep in line with the parameters of getStringToken().

Also this assumes you have an array big enough for the data

[ Headcoded so may need tweaking ]
Luca91
11
Years of Service
User Offline
Joined: 1st Sep 2012
Location: Italy
Posted: 17th Nov 2012 12:22
Works perfectly , many thanks
Auger
12
Years of Service
User Offline
Joined: 21st Aug 2011
Location: Out There
Posted: 17th Nov 2012 18:18
Quote: "Quote: "ReadInteger reads in binary values not strings."
I'd never even considered that, well spotted.

So for the same reason, writing strings is a good idea so that you can check the contents in notepad "


Yeah that's one of the reasons I use it sometimes. So people can't see the numbers in notepad.

Auger
Ancient Lady
Valued Member
20
Years of Service
User Offline
Joined: 17th Mar 2004
Location: Anchorage, Alaska, USA
Posted: 17th Nov 2012 21:07
I'm now at the level building stage for my game.

Originally all the files for the levels were in straight text. Which would allow a player to mess with the levels if they could find the files.

I modified my file handler class to work with a file in either text or binary mode by setting a switch when the file is opened.

Then I set my level editor to read the text version, let me do edits and write back the text file and create a binary version. Now the game itself reads the binary version. So, when I distribute it, the players won't be able to mess with the levels for better scores.

Cheers,
Ancient Lady
AGK Community Tester
JimHawkins
14
Years of Service
User Offline
Joined: 26th Jul 2009
Location: Hull - UK
Posted: 18th Nov 2012 14:02 Edited at: 18th Nov 2012 16:26
Saving binary files can have problems, as I know to my cost! They're very hard to extend, and backward and forward compatibility can be a problem, as can storing strings, since you need to allocate binary space.

There's a fairly simply way around this. I try wherever possible to use human readable formats - usually strings. If you don't want people to read them, encode them and then decode them. Here are two very simple functions to show the idea - these are in Pascal, but easily adapted to Basic or C/C++.



The Encode function takes a string and outputs another string that is XORed for each character. In this case it's using the loop index, but it can be anything.

TheDecode function does exactly the same, and returns the original string. Note: I'm using ansiString here because modern versions of Delphi use Unicode strings as the basic string type.

The text file will look like garbage to anybody looking at it:

Input:


Output:


Passed through the Decode function this restores the original perfectly.

Notice that the numbers 12345 turn into 11111 - pretty hard to hack that! Also that I'm adding 1 to the XOR value. This is to avoid a potential null in the output string, which can be a problem with null-terminated strings.

Using this technique you don't have to allocate binary string space, and if you later introduce more values, older systems can still use what was there and ignore new stuff.

-- Jim DO IT FASTER, EASIER AND BETTER WITH AppGameKit FOR PASCAL

Login to post a reply

Server time is: 2024-05-05 11:46:41
Your offset time is: 2024-05-05 11:46:41