Sign in to follow this  
LordCube

C programming structure char arrays

Recommended Posts

Hey, I'm programming using SDL and C in DevC++. I am trying to create a struct array and within each struct have a char array. struct console_struct { int letteramount; int linewidth; int currentletter; int currentwidth; char lineletter[100]; }; struct console_struct console[CON_history]; However after I compile my code and start writing into the array I find its only like 8 chars long. The odd thing about it is when I change the specified size of the array (100) to something like 52. Then the array suddenly appears to be a different size but still not 52 chars long. Could any one please enlighten me into what I have done wrong and how to correct my problem?

Share this post


Link to post
Share on other sites
I have been debugging using printf etc. It returns garble once it passes 8 or so characters. The project is also visual. It's a type of console that I'm making where I can type into it. The lineletter arrays are each line of the console.

I have got the program to display what I type into the line. So when lineletter is defined as [100] and I type into the console it suddenly stops recieving input.

Input into the console is written like so
// Add character to the current console string
console[fastvar].lineletter[fastvar2+1] = '\0';
console[fastvar].lineletter[fastvar2] = c;
TTF_SizeText(font, console[fastvar].lineletter, &console[fastvar].linewidth, NULL);

Im positive that the problem lies in where the structure is defined.

Share this post


Link to post
Share on other sites
Just been messing around with it.
Rearranged it to this again


#define maxletter 100
struct console_struct
{
char lineletter[CON_maxletter];
int letteramount;
int linewidth;
int currentletter;
int currentwidth;
};
struct console_struct console[CON_history];


Compile, Run, *ERROR
Compile, Run, *ERROR
Compile, Run, works now?? wth?

Do you think this is the compilers fault?

Share this post


Link to post
Share on other sites
Quote:
Original post by LordCube
Compile, Run, *ERROR
Compile, Run, *ERROR
Compile, Run, works now?? wth?

Do you think this is the compilers fault?

No, and neither is the struct at fault. Some other part of your code is corrupting the stack/heap by writing to one of the arrays with an out of bound index, for example.

Share this post


Link to post
Share on other sites
Not working again :(


// PART OF GLOBALS.H

#define CON_history 25 // INIT // Amount of lines to go in console history
#define CON_width 800 // INIT // Width of the Application goes here
#define CON_height 600 // INIT // Height if the Application goes here
#define CON_lineh 15 // INIT // Height of each line - can be font h
#define CON_depth 10 // INIT // Amount of lines shown on console drop
#define CON_alpha 192 // INIT // Amount of alpha console background has
#define CON_dropspeed 5 // INIT // Speed that the console drops down
#define CON_maxletter 100 // INIT // Maximum amount of letters to go in a console line

extern int CON_pixeldepth;
extern int CON_cursorblink;
extern int consoletimer;
extern int shiftdown;
int shiftdown;
int CON_pixeldepth;
int CON_cursorblink;
int consoletimer;

/* Create the Console Array */
struct console_struct
{
char lineletter[CON_maxletter+1];
int letteramount;
int linewidth;
int currentletter;
int currentwidth;
};
struct console_struct console[CON_history];

// MAIN LOOP
while (!quit)
{
Update_game();

/* Check for events */
while (SDL_PollEvent(&event))
{
switch (event.type)
{
case SDL_MOUSEBUTTONDOWN:
if (event.type==SDL_MOUSEBUTTONDOWN) {
// Mouse button down code here
}
break;
case SDL_MOUSEBUTTONUP:
if (event.type==SDL_MOUSEBUTTONUP) {
// Mouse button up code here
}
break;
case SDL_MOUSEMOTION:
if (event.type==SDL_MOUSEMOTION) {
// Mouse motion code goes here
}
break;
case SDL_KEYDOWN:
if (event.type==SDL_KEYDOWN) {
// Record current key pressed
current_key = event.key.keysym.unicode;
current_code = event.key.keysym.scancode;
// If shift is down
if ((current_code == 54)||(current_code == 42))
shiftdown = 1;
// Report key pressed
printf("%d\n", current_code);
// Input key into the console
Console_Input(current_key);
// If the key was esc then close app
if (current_code == 1)
quit = 1;
}
break;
case SDL_KEYUP:
if (event.type==SDL_KEYUP) {
current_key = 0;
shiftdown = 0;
}
break;
case SDL_QUIT:
if (event.type==SDL_QUIT) {
// Quit code here
quit = 1;
}
break;
default:
break;
if (current_key > 0) {
switch(current_key){
/* Escape Key */
case 1:
quit = 1;
break;
}
}
}
}
}
shutdown();
return 0;

// CONSOLE INPUT
/* Function to take and add pressed characters to the screen */
void Console_Input(key)
{
// If the enter key was pressed
if (current_code == 28) {
AcceptConsoleCommand();
ClearConsoleInputLine();
}
// If the key was backspace delete the last input
if (current_code == 14) {
if (console[CON_history].letteramount > 1) {
console[CON_history].lineletter[console[CON_history].letteramount-1] = '\0';
console[CON_history].letteramount--;
TTF_SizeText(font, console[CON_history].lineletter, &console[CON_history].linewidth, NULL);
consoletimer = 0;
return;
}
}
// Create fastvar variables
int fastvar = CON_history;
int fastvar2 = console[fastvar].letteramount;
// Insert Space if it was pressed
if (current_code == 57) {
InsertChar(' ');
}
// Insert special char if pressed
// '-'
if (current_code == 12) {
if (shiftdown == 1) {
InsertChar('_');
return;
}
InsertChar('-');
return;
}
// ','
if (current_code == 51) {
if (shiftdown == 1) {
InsertChar('<');
return;
}
InsertChar(',');
return;
}
// '.'
if (current_code == 52) {
if (shiftdown == 1) {
InsertChar('>');
return;
}
InsertChar('.');
return;
}
// Make sure key is a valid alpha numeral
if (isalnum(key)==0)
return;
// if shift is down
if (shiftdown == 1)
key = toupper(key);
// Convert to a character
char c = (char)key;
// If there is a space free for a new letter
if (console[CON_history].letteramount == CON_maxletter) {
return;
}
// Add character to the current console string
console[fastvar].lineletter[fastvar2+1] = '\0';
console[fastvar].lineletter[fastvar2] = c;
TTF_SizeText(font, console[fastvar].lineletter, &console[fastvar].linewidth, NULL);
// If the line is too long for this character
if (console[fastvar].linewidth >= CON_width) {
console[fastvar].lineletter[fastvar2] = '\0';
TTF_SizeText(font, console[fastvar].lineletter, &console[fastvar].linewidth, NULL);
} else {
// If the line is small enough to fit this character
console[CON_history].letteramount += 1;
}
}




[Edited by - Zahlman on September 10, 2009 8:19:09 PM]

Share this post


Link to post
Share on other sites
Quote:
Original post by LordCube
Not working again :(


// ...
struct console_struct console[CON_history];

// ...
if (console[CON_history].letteramount > 1) {
console[CON_history].lineletter[console[CON_history].letteramount-1] = '\0';
console[CON_history].letteramount--;
TTF_SizeText(font, console[CON_history].lineletter, &console[CON_history].linewidth, NULL);
// ...


All of these accesses to the 'console' array are out of bounds.

By the way, where do all these magic numbers for 'current_code' come from? And what kind of variable name is 'fastvar'?

And where is the code to move lines down in the array?

Share this post


Link to post
Share on other sites
The magical Current code and key comes from the SDL event in the main loop


current_key = event.key.keysym.unicode;
current_code = event.key.keysym.scancode;


Defined in globals.h as so

/* Variables */
extern int quit;
extern int current_key;
extern int cursor_x;
extern int cursor_y;
extern int shiftdown;
extern int current_code;

/* Variables */
int quit;
int current_key;
int cursor_x;
int cursor_y;
int shiftdown;
int current_code;


I have linked to globals in the console.c file where ConsoleInput is found. I did not post all my code. Other functions are found in different .c files all linked to globals.h. I have only posted relevant code.

I dont know what you mean by out of bounds but I assume you mean that it cant be accessed. It can be accessed and written to. Theres a tone of code and its not written very well so I only posted the relevant functions. Not the whole project.

'fastvar' is my type of variable name. It's not your project so you dont have to worry about what I call my variables. Please just help me find the error.

Share this post


Link to post
Share on other sites
Quote:
Original post by LordCube
The magical Current code and key comes from the SDL event in the main loop


current_key = event.key.keysym.unicode;
current_code = event.key.keysym.scancode;



No. That's not what I was asking about. "Magic numbers". How do you know what numbers to compare the variable to? How does the number 51 have anything to do with the ',' character (whose ASCII value is 44), for instance?

Quote:
I dont know what you mean by out of bounds but I assume you mean that it cant be accessed. It can be accessed and written to.


No, it cannot. It is not legal to access or write element CON_history of an array with size CON_history. The array indices start at 0, and there are CON_history many elements. The last one has the index CON_history - 1.

Quote:
'fastvar' is my type of variable name. It's not your project so you dont have to worry about what I call my variables.


That's true; I don't have to help you. But at the end of the day, you're the one who has to read your code and figure out what 'fastvar' means. I am trying to help you by encouraging you to give things logical names. The reason you are given free choice in your variable names is so you can choose something that makes sense.

Quote:
Please just help me find the error.


I already showed you one source of error. That might not be the only problem, of course.

Share this post


Link to post
Share on other sites
Ok, thx for that. Programming is just a hobby of mine that I do in my own spare time so I dont excatly know alot.

Yes I have broken a rule. These numbers are apparently set by SDL, unicode and ASCII. I used printf to work out the value of the key I was pressing then just directly reffered to it.

Ok. Thanks for that.

Thanks for showing your concern. fastvar did make sense to me but if it helps others I'll change it.

Yes, i can spot out alot of errors within my code. All of which I know the problem however theres one that does not make sense which needs to be removed. This problem is the one stated in the first post. Does any one know how to fix it?

I did more tests. Everything leads to globals.h where its defined. I rewrote most of the project without as many for loops, without the struct and defined every char array manually. (lineletter1, lineletter2) etc.
This is a terrible way to do it and I should know better however I only did this to see if it works that way. I still have the original project.
Anyway, after rewriting most of the code manually. I compiled the project and... fine. It works perfectly. It must be struct where the problem lies.
Any one make sense of this?

I link my project together using several .c files all linked to one .h globals file. Is this method acceptable or have I been coding the wrong way all this time?

Share this post


Link to post
Share on other sites
Have you traced through it in a debugger? And quit ignoring perfectly good advice. There is nothing wrong with the struct definition, so get that out of your head. You also completely ignored zahlman's comment about what is absolutely an error, where you are accessing the array out of bounds.

Share this post


Link to post
Share on other sites
Quote:
Original post by LordCube
Yes I have broken a rule. These numbers are apparently set by SDL, unicode and ASCII. I used printf to work out the value of the key I was pressing then just directly reffered to it.
Those values are defined by SDL with symbolic names as well. See here for a big table. For example, SDLK_LESS is defined as 51.

I should also point out that the actual keys that these correspond to are locale-dependant. For example, on a german keyboard, SDLK_Q corresponds to the "Z" key. Other keys that cause problems are ones like SDLK_QUOTEDBL (") which can be mapped to different keys depending on locale. You should be using the event.key.keysym.unicode for all printable values (things like SLDK_BACKSPACE, you can't really avoid it).
Quote:
Original post by LordCube
Yes, i can spot out alot of errors within my code. All of which I know the problem however theres one that does not make sense which needs to be removed. This problem is the one stated in the first post. Does any one know how to fix it?
You still haven't explained how you're coming to the conclusion that the array is only 8 characters long - how are you measuring the length?

Share this post


Link to post
Share on other sites
Quote:
Original post by smitty1276
Have you traced through it in a debugger? And quit ignoring perfectly good advice. There is nothing wrong with the struct definition, so get that out of your head. You also completely ignored zahlman's comment about what is absolutely an error, where you are accessing the array out of bounds.


I didn't express myself properly.
Zahlman identified the error and its fixed. It WAS the definition of the struct in globals. To fix it I could either go through my whole code replaceing CON_history with CON_history-1 or just simply put +1 onto the definition. I understand everything he has said. Thanks Zahlman!

Thanks for that explanation Codeka. I doubt my projects will ever become public.

PROBLEM SOLVED, THREAD CLOSED

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this