Reading a file letter by letter into an array

Hi, I am relatively new to programming from scratch and I am encountering a problem trying to easily load ASCII art into a text based game I'm trying to make.

The way I'm trying to do it is by starting with a txt document (to allow for easy construction of the art) and writing a program that opens the file (the file location is hard coded into the program) and will read it letter by letter into an array of type char.

My "sprites" (A.k.a. ascii art) specifications are hard coded into the program as well, although I would love to find a way to automate the process of finding the dimensions (how many cells high and wide the ascii art is). Also I would like to have the array that keeps track of the chars that will be used for the ASCII art in the structure as well so I do not have to write several lines of extra code to initiate a new sprite every time I add a piece of artwork into the game. Here are the structures I am using to handle sprites along with the way I initiate them in main():
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
struct Pos
{
	int x;
	int y;
};

struct Size
{
	int width;
	int height;
};
struct Sprite
{
	Pos position;
	Size dimension;
	char transparent_char; //this is the character that will be used to
                               //represent transparency (the game will not
                               //draw over whatever is behind the sprite in
                               //the area that is occupied by this symbol
};

int main()
{
	Sprite smiley = {{0, 0}, {17, 8}, '$'}; //as you can see, the numbers
	                                        //for dimension are hard coded
                                                //into the game...
}


Now this is a sample of the text document I want to import (it is saved in the same folder as the program's .cpp file and is saved as smiley.txt with ANSI encoding, but that can be changed if needed):
1
2
3
4
5
6
7
8
9
$$$$.-""""""-.$$$$
$$.'          '.$$
$/   O      O   \$
:                :
|                |
: ',          ,' :
$\  '-......-'  /$
$$'.          .'$$
$$$$'-......-'$$$$


Now, the document is 18 characters wide by 9 characters tall. How can I get c++ to open it like this: (this is just an rough sketch of how I'm trying to get it to work, not actual code)
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
54
55
56
57
58
59
60
61
62
63
#include<stdio.h>

struct Pos
{
	int x;
	int y;
};

struct Size
{
	int width;
	int height;
};
struct Sprite
{
	Pos position;
	Size dimension;
	char transparent_char;
	char image[]; //an array that contains the char values that will
                      //make up the image
};

int main()
{
	// Code to open file goes here

	int sprite_x = Chars_Wide_From_File; //0 will count. So if it is 9 tall 
	int sprite_y = Chars_Tall_From_File; //the value would be 8.

	int sprite_size = (sprite_x +1)*(sprite_y+1); //add one because it
						      //starts at 0

	//if this math comes out right, the total size of the array for this
	//text file (smiley.txt) should hold 162 chars

	Sprite smiley = {{0 , 0}, {sprite_x, sprite_y}, '$'};
	sprite.image[sprite_size];

	//I'm using less-than as opposed to less-than or equal too because it 
	//starts at 0 and will run to 161 meaning it will run 162 times...

	for( i = 0, i < sprite_size, i++)
	{
		char current_letter = letter_at_position_i_in_file

		//code that adjusts for the various symbols that the compiler
		//may miss-intemperate as code goes here

		sprite.image[i] = current_letter;

		//I don't need to import the chars location into the array
		//because (using the sprites dimensions) I can figure that out
		//on the fly with some simple math.
	}
	
	//A simple way to test the image
	for(i=0, i > sprite_size, i++)
	{
		printf("%c", sprite.image[i]);
		if( (i!= 0) && ((i % sprite_x) == 0))
			printf("\n");
	}
}

Couple things first.

Static arrays have to have their size specified at declaration, and this size has to be static, not dynamic. char image[]; is not an acceptable declaration because it does not specify the size of the array. Nor is it acceptable to pass in the array size as a variable.

If you want to have dynamic array size, you have to use a pointer and dynamic array allocation. In your struct, declare char * image;

Later, after determining the size of the sprite use image = new char[sprite_size];.

However, with this dynamic allocation comes more maintainance on your part, because you are responsible for deallocating all memory you allocate. So when you are done with that sprite, you must call delete[] image; The brackets are essential, even though they are empty. That call is not the same as delete image;.

You can incorporate the sprite size into the text file as well using what is referred to as header information. This is common to most file formats out there, not just image files. You arbitrarily define the format of your header, and then read in the header and use the values read in to read in the rest of the file. As a simple example, the very first line of your text file could contain two numeric values that are the sprites height and width. You read in that line, stash the height and width in the appropriate variables, then read in the rest of the file based on those values. The only additional value I'd recommend for the header is a version number, and this should be the very first parameter in the file. You can then read in that number first, and based on that number, process the rest of the file. With this version number, you can modify your file format down the road and still write code that will support older versions of the format.
I agree that a static array must have it's size specified and that in order to have a dynamic array you must declare it as a pointer. However their is a third type of array that I am referring to known as a flexible array member which, from my understanding, is supported by c.

If you would like to check my source:
ISO/IEC 9899 Section 6.7.2.1, paragraph 16
link: http://www.open-std.org/JTC1/SC22/wg14/www/docs/n1124.pdf

Correct me if I'm wrong but this should work... however I do not have the slightest clue how to implement it.
The array will work. I just tested it and it works as expected.

Anyway, there is no way to open the file like this. You will need to parse the newlines yourself (or use getline() and add one after every call to getline())
tlchack5,

The flexible array member is still a dynamically allocated scenario, though in that case the entire struct has to be dynamically allocated (with enough memory being allocated for regular struct members & the size of the array you wish to use) , otherwise the array member is invalid.

I believe you also have to use malloc and free, as new and delete do not support that type of struct allocation, and it's your responsibility to allocate the necessary memory to contain the entire struct & array. For your struct, something like...

1
2
3
4
5
// Declaring a Sprite pointer and allocating the size of the struct plus the size of the sprite array for it
Sprite * smiley = malloc( sizeof(struct Sprite) + sprite_size * sizeof(char));

//Later on, when you're done with the sprite, have to free the allocated memory
free(smiley);


Not exactly the cleanest method of accomplishing what you want. Also, it should be mentioned that there's no guarantee that modern C++ compilers will correctly implement this somewhat obscure element of the C standard either.
Topic archived. No new replies allowed.