Opening a file problem

Pages: 12
Hi ,

I have one strange problem.

I have one text file with this format.

1
2
3
4
[Level01]
001.001.002.002_001.000.000.000_001.001.002.002_000.000.000.000_001.001.002.002_000.000.000.000_001.001.002.002_000.000.000.000_001.001.002.002_000.000.000.000_001.001.002.002_000.000.000.000_001.001.002.002_000.000.000.000_001.001.002.002_000.000.000.000_001.001.002.002_000.000.000.000_001.001.002.002_000.000.000.000_001.001.002.002_000.000.000.000_000.000.000.000_000.000.000.000_000.000.000.000_000.000.000.000_000.000.000.000_000.000.000.000_000.000.000.000_000.000.000.000_000.000.000.000_000.000.000.000_000.000.000.000_000.000.000.000_000.000.000.000_000.000.000.000_000.000.000.000_000.000.000.000_000.000.000.000_000.000.000.000_000.000.000.000_000.000.000.000_000.000.000.000_000.000.000.000_000.000.000.000_000.000.000.000_000.000.000.000_000.000.000.000_000.000.000.000_000.000.000.000_
000.000.000.000_001.001.002.002_000.000.000.000_001.001.002.002_000.000.000.000_001.001.002.002_000.000.000.000_001.001.002.002_000.000.000.000_001.001.002.002_000.000.000.000_001.001.002.002_000.000.000.000_001.001.002.002_000.000.000.000_001.001.002.002_000.000.000.000_001.001.002.002_000.000.000.000_001.001.002.002_000.000.000.000_000.000.000.000_000.000.000.000_000.000.000.000_000.000.000.000_000.000.000.000_000.000.000.000_000.000.000.000_000.000.000.000_000.000.000.000_000.000.000.000_000.000.000.000_000.000.000.000_000.000.000.000_000.000.000.000_000.000.000.000_000.000.000.000_000.000.000.000_000.000.000.000_000.000.000.000_000.000.000.000_000.000.000.000_000.000.000.000_000.000.000.000_000.000.000.000_000.000.000.000_000.000.000.000_000.000.000.000_000.000.000.000_000.000.000.000_
001.001.002.002_000.000.000.000_001.001.002.002_000.000.000.000_001.001.002.002_000.000.000.000_001.001.002.002_000.000.000.000_001.001.002.002_000.000.000.000_001.001.002.002_000.000.000.000_001.001.002.002_000.000.000.000_001.001.002.002_000.000.000.000_001.001.002.002_000.000.000.000_001.001.002.002_000.000.000.000_001.001.002.002_000.000.000.000_000.000.000.000_000.000.000.000_000.000.000.000_000.000.000.000_000.000.000.000_000.000.000.000_000.000.000.000_000.000.000.000_000.000.000.000_000.000.000.000_000.000.000.000_000.000.000.000_000.000.000.000_000.000.000.000_000.000.000.000_000.000.000.000_000.000.000.000_000.000.000.000_000.000.000.000_000.000.000.000_000.000.000.000_000.000.000.000_000.000.000.000_000.000.000.000_000.000.000.000_000.000.000.000_000.000.000.000_000.000.000.000_


I didn't put whole file here, is huge.

This file contains one level map walls.

I have one array char type with name
 
char* levels[20][50][50][4];


Also I have and one struct with name module.

1
2
3
4
5
6
7
8
9
10
11
12
struct my_module
{
       int map_x;
       int map_y;
       char dummy[10];
       char comma[2];
       char wall_n[5];
       char wall_s[5];
       char wall_w[5];
       char wall_e[5];
     
} module;


This struct holds the map data of the level text file above.
The file you see has 50 squares horizontal and 50 squares vertical.

I put ony first 3 lines.

As you see in the text file is like this 001.001.001.001_002.002.002.002_001.001.001.001 ....

This means each 001. is one side of one square each square finishes at "_" and start the next square of the map.

I use this code to load my file...

1
2
3
4
5
6
7
8
9
10
int Load_module()
{
        module_file_number = fopen("c:/module.txt","rw");
        
        fread(module.dummy,9,1,module_file_number); //This line bypass the "[Level01]" string
        fread(module.comma,1,1,module_file_number); //This goes to next line

.
.
.


And the code continue in the rutine I read the 50x50 map.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
.
.
.
//These loops loads the map horizontal and vertical
//In this case loads only the first 1x1 square of the map as test

    for (module.map_x=1; module.map_x<=1; module.map_x++)
    {

        for (module.map_y=1; module.map_y<=1; module.map_y++)
        {
.
.
.


In the body of these two loops there is the code which loads each square
and fill my char *levels[20][50][50][4] array.

The code continues...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
       //This line reads only the first 3 bytes , the "001" string and
       //stores the string "001" in one member variable of struct module with
       //name wall_n this variable is char type
       fread(module.wall_n,3,1,module_file_number);
       //This line stores in levels array at levels[1][1][1][1] the string "001"
       //from member variable wall_n of struct module
       levels[1][module.map_x][module.map_y][1]=module.wall_n;
       //This line read the "." after the "001" string of the file.
       fread(module.comma,1,1,module_file_number);

       //I use this code more three times to read all sides of walls of my square.
       //Each 001.001.001.001_ is one square on the map.

        //The same code store the wall_s variable and fills the array
        fread(module.wall_s,3,1,module_file_number);
        levels[1][xx][module.map_y][2]=module.wall_s;
        fread(module.comma,1,1,module_file_number);

        //The same code store the wall_w variable and fills the array
        fread(module.wall_w,3,1,module_file_number);
        levels[1][xx][module.map_y][3]=module.wall_w;
        fread(module.comma,1,1,module_file_number);

        //The same code store the wall_e variable and fills the array
        fread(module.wall_e,3,1,module_file_number);
        levels[1][xx][module.map_y][4]=module.wall_e;
        fread(module.comma,1,1,module_file_number);

        //After this I have all my walls filled correct
        //wall_n , Wall North
        //wall_s , Wall South
        //wall_w , Wall West
        //wall_e , Wall East
       }
    }

    fclose(module_file_number);

    return 0;
}


This code reads the strings for each wall and fills the squares of the map array levels
In this case stores one the 1,1 map

Fills the level 1 at 1 x 1 all walls around.
levels[1][1][1][1]
levels[1][1][1][2]
levels[1][1][1][3]
levels[1][1][1][4]

All of these works correct.

The problem is when I increase my loop from module.map_x<=1; to module.map_x<=2;

1
2
    for (module.map_x=1; module.map_x<=1; module.map_x++)
    {


If I increade th module.map_x variable from 2 to 50 programm crashes.
1
2
    for (module.map_x=1; module.map_x<=2; module.map_x++)
    {


The thing which is crashing is the for

I tryed to fill manualy the array , and program will crash again

The example:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42

module.map_x=1; module.map_y=1;

        fread(module.wall_n,3,1,module_file_number);
        levels[1][module.map_x][module.map_y][1]=module.wall_n;
        fread(module.comma,1,1,module_file_number);

        fread(module.wall_s,3,1,module_file_number);
        levels[1][module.map_x][module.map_y][2]=module.wall_s;
        fread(module.comma,1,1,module_file_number);

        fread(module.wall_w,3,1,module_file_number);
        levels[1][module.map_x][module.map_y][3]=module.wall_w;
        fread(module.comma,1,1,module_file_number);

        fread(module.wall_e,3,1,module_file_number);
        levels[1][module.map_x][module.map_y][4]=module.wall_e;
        fread(module.comma,1,1,module_file_number);

module.map_x=2; module.map_y=1;

        fread(module.wall_n,3,1,module_file_number);
        levels[1][module.map_x][module.map_y][1]=module.wall_n;
        fread(module.comma,1,1,module_file_number);

        fread(module.wall_s,3,1,module_file_number);
        levels[1][module.map_x][module.map_y][2]=module.wall_s;
        fread(module.comma,1,1,module_file_number);

        fread(module.wall_w,3,1,module_file_number);
        levels[1][module.map_x][module.map_y][3]=module.wall_w;
        fread(module.comma,1,1,module_file_number);

        fread(module.wall_e,3,1,module_file_number);
        levels[1][module.map_x][module.map_y][4]=module.wall_e;
        fread(module.comma,1,1,module_file_number);

//e.t.c....
.
.
.


In few words , its like these variables can be used only once.
wall_n , wall_s , wall_w , wall_e



What could be the problem?

Thank you...
Last edited on
char* levels[20][50][50][4];

Why is levels char* and not char?


If I remove the asterisc * the compiler drops this error

Also all my stores of data are strings "000" , "001" , "002" etc..

16 C:\Eob4c\Main.cpp In file included from Main.cpp
C:\Eob4c\Draw_Walls_North.h In function `int Draw_Walls_North(BITMAP*)':
44 C:\Eob4c\Draw_Walls_North.h ISO C++ forbids comparison between pointer and integer
48 C:\Eob4c\Draw_Walls_North.h invalid conversion from `char' to `const char*'
48 C:\Eob4c\Draw_Walls_North.h initializing argument 2 of `char* strcpy(char*, const char*)'
59 C:\Eob4c\Draw_Walls_North.h ISO C++ forbids comparison between pointer and integer
63 C:\Eob4c\Draw_Walls_North.h invalid conversion from `char' to `const char*'


All the program uses this array as char * and if I remove the char
I have more 2000s of errors.

But in the load module function drops this error

C:\Eob4c\Load_module.h In function `int Load_module()':
34 C:\Eob4c\Load_module.h invalid conversion from `char*' to `char'

Last edited on
Ok. This is going to be a bit off-handed. However.

Instead of using fread(). This sort of file would be better read using a C++ IOStream e.g file >> wall_w; or (perhaps even better) the C fscanf() function.

I'd even be tempted to load the whole file into a vector. Then split each line into arrays using strtok(). This would give you more flexibility to ensure the file meets the required format.

fread() is good. But is really better suited to loading binary files.

My suggestion would be after each fread() function. Debug output (either cout/printf or to a file) what was read in. This will validate that your variables are actually being read correctly.

If your using an IDE with an integrated debugger. Then put some breakpoints and watches on your variables to see if it's not doing something funny.

e.g. If could be reading in \n chars somewhere without you catering for them.
The fread reads my file correct

And I see my first wall at 1 , 1 in my map

If I will continue to load the 2 , 1 in the map , then crashes.

Is there an function which clears my old used wall_n , wall_s ... variables?

I thing my variables was read correct.
Last edited on
The \n at the end of line 1 isn't causing any problems?
No , I don't have reach all 50 squares yet , at the start of the second square
program crashes so.

The code reads the fist square 000.000.000.000_
When it will enter to the next crashes.

When I load the [Levels01] string and pass the first line
Programm work well so there is no problem about \n

The problem could be when I re-use the same variables.

Now I tryied to read the first wall of the second square and worked
But If I read the second wall of the second square crashes.

----First square---_--Second square but only the first wall
001.001.001.001_001.crash....


Last edited on
Ahh ok.

Your treating your arrays as 1->4 when they are not. They are 0->3.

levels[1][module.map_x][module.map_y][4]=module.wall_e;
4 is not a valid index.
I put the variables from 1 to 4

The capacity of array is levels[20][55][55][4]; in fact

because I checking walls more 50x50

But the sides are 1 to 4

The player is moving through 50 x 50

But the limits for program mechanism are from -3 to 53

So the array takes negative values , because the programm is working
If I put some wall manual.

levels[1][-1][-2][4]="001";

This working.


I use allegro library for my sprites. I can upload all programm to see
if you have allegro installed.
Last edited on
Yes. But you are not a computer :P So you think from 1->4.

e.g
1
2
3
4
5
int array[4];

array[1] = 3; // Ok. But this is the 2nd element
array[4] = 3; // Bad. 
array[0] = 3; // Ok. The first element 


Chances are array[4] = 3 will work. But you have just written to an unknown memory location. While this will work, chances are it'll cause somewhere else in the application to crash or unexplained behavior.

levels[1][-1][-2][4]="001";

This working.


Err.. You cannot just "make up" indexes for your array.

if I define an array as levels[10] then the ONLY valid indexes are 0-9. While other values MAY work; you will be writing into unknown memory space and this WILL cause problems in your application.
levels[1][1][1][1]="001"
levels[1][1][1][2]="001"
levels[1][1][1][3]="001"
levels[1][1][1][4]="001"

The index levels[1][1][1][0] is empty
or is takes some default value "000"
I never uses values as

levels[0][0][0][0]=something;

I assume the first is the 1

comma strings as "." and "_" stored in comma variable
like dummy variable.

Last edited on
1
2
3
4
levels[1][1][1][1]="001"
levels[1][1][1][2]="001"
levels[1][1][1][3]="001"
levels[1][1][1][4]="001"


is wrong.

1
2
3
4
levels[0][0][0][0]="001"
levels[0][0][0][1]="001"
levels[0][0][0][2]="001"
levels[0][0][0][3]="001"


is valid.
Yes , but I don't use the index 0

If I fill manualy the numbers without load them from file , with fread
all works correct.


I use this to fill everything include the 0 indexes and I empty the
walkable area with "000" other area is files with "001" and "002"
only from map_x 1-50 map_y 1-50 all walls 1-4

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
int init_levels_array()
{
 
    //I fence my all levels with walls and fill my array correct 
    //I fill all matrix from -4 to 53 all with "001"
    for (party.level=1; party.level<=20; party.level++)
    {
        for (party.x=-4; party.x<=53; party.x++)
        {
            for (party.y=-4; party.y<=53; party.y++)
            {
            levels[party.level][party.x][party.y][1]="001";
            levels[party.level][party.x][party.y][2]="001";
            levels[party.level][party.x][party.y][3]="001";
            levels[party.level][party.x][party.y][4]="001";
            }
        }
    }            
    //I fill all matrix from -4 to 52 all with "002" only even squares
    //Like a chess board.
    for (party.level=1; party.level<=20; party.level++)
    {
        for (party.x=-4; party.x<=52; party.x+=2)
        {
            for (party.y=-4; party.y<=52; party.y+=2)
            {
            levels[party.level][party.x][party.y][1]="002";
            levels[party.level][party.x][party.y][2]="002";
            levels[party.level][party.x][party.y][3]="002";
            levels[party.level][party.x][party.y][4]="002";
            }
        }
    }            


   //I empty my solid map in this area with empty squares "000"
    for (party.level=1; party.level<=20; party.level++)
    {
        for (party.x=1; party.x<=50; party.x++)
        {
            for (party.y=1; party.y<=50; party.y++)
            {
            levels[party.level][party.x][party.y][1]="000";
            levels[party.level][party.x][party.y][2]="000";
            levels[party.level][party.x][party.y][3]="000";
            levels[party.level][party.x][party.y][4]="000";
            }
        }
    }            
    
    
    return 0;
}


This code works very well.
Last edited on
Errr... Just because you don't "use" index 0. Doesn't mean it's not there.

1
2
3
4
5
6
7
8
9
10
11
char* levels[20][50][50][4];

// A can only be 0-19
// B can only be 0-49
// C can only be 0-49
// D can only be 0-3
levels[A][B][C][D]=X;

// D is 4.. This is WRONG.
// And a likely cause of crashes.
levels[1][module.map_x][module.map_y][4]=module.wall_e;


1
2
3
4
5
6
7
8
9
10
11
12
13
14
    //I fence my all levels with walls and fill my array correct 
    for (party.level=1; party.level<=20; party.level++) // WRONG
    {
        for (party.x=-4; party.x<=53; party.x++) // WRONG
        {
            for (party.y=-4; party.y<=53; party.y++) // WRONG
            {
            levels[party.level][party.x][party.y][1]="001";
            levels[party.level][party.x][party.y][2]="001";
            levels[party.level][party.x][party.y][3]="001";
            levels[party.level][party.x][party.y][4]="001"; // WRONG
            }
        }
    }  


WTF!?

//I fence my all levels with walls and fill my array correct

WRONG.

Read the following statement CAREFULLY

When you declare an array. The values that array can assign to are from 0 to the limit - 1.

e.g Array[10] can ONLY assign to 0 through to 9. You will be ALLOWED to assign to other indexes but this is NOT CORRECT and WILL cause CRASHES, MEMORY OVERFLOWS, MEMORY LEAKS and BUFFER UNDERRUNS


You CANNOT make up indexes (e.g. -3). Programming doesn't work like this.
Last edited on
here is a link explaining how to use arrays. Please study this carefully.

It does appear you will be changing a fair amount of code to get your game to work. While I do applaud you for trying to develop a game (they are notoriously difficult) you do have alot about the C++ language to learn. I would suggest you spend some more time studying the basic concepts of C++ before trying such difficult projects.

Arrays:
http://www.cplusplus.com/doc/tutorial/arrays.html

File I/O (note: fread() is C, not C++)
http://www.cplusplus.com/reference/iostream/
I know , the zeroes are numbers in the programming.
I will say it else

I have and array levels[20][50][50][4];
Includes the zeroes
But the zeros are not empty have something in , have the "000"

Like this

levels.......[0]="000"
levels.......[1]="001"
levels.......[2]="001"
levels.......[3]="001"
levels.......[4]="001"

And I am checking only from index 1 if there is somethimg

But my engine is working like this

If you are at position 1x1 on the map
or at least 0x0 on the map

You need to check If you have a wall in front of you
this means

if (levels[party.level][party.x][party.y-1][1]=="001") or something else

this means if am I on 1x1 position , I need to check if there is something at
1x0 position. This woking
But in my front wall , behind of this wall there is another wall at position

1x-1 - this means 2 square fars of my front wall.

Also there are and 3 square behind from these 2 walls at position -3

This is out of bounds of the array but , can take negative values because does not deglared as unsigned so negative can be stored.

So my for is from -3 to 54 loop fills correct my walls.

The problem is not of my walls.

My dungeon crawlling engine is working perfect , even I put negative values in my walls. (Out bounds of my levels array , but in fact
is from minus infinity to plus 55 are my limits of my array.

The problem is I can't load the file.
why manualy values stored well , and when loaded from file are wrong?

:)

This is out of bounds of the array but , can take negative values because does not deglared as unsigned so negative can be stored.

No. The limits of the array do not depend on the type of the elements of the array.
T array[10] goes from array[0] to array[9]. No exceptions. array[-1] and below and array[10] and above are all invalid
While it's not impossible to write to or read from other offsets, you would be doing so outside of the array and possibly step on different variables or even the stack if you're unlucky enough.
Pages: 12