|
|
View previous topic - View next topic |
Author |
Message |
Ninkazu Demon Hunter
Joined: 08 Aug 2002 Posts: 945 Location: Location:
|
Posted: Fri Jun 04, 2004 7:47 pm Post subject: code snippet - won't stop crashing |
[quote] |
|
I'm writing a map editor in c++/allegro and I got to the save function and realized I needed something like INPUT in QB. I through this together and all it does is crash. Ideas, anyone?
Code: | char* dinput(const char* message, int x, int y, int limit, int col)
{
textout(screen, font, message, x, y, col);
int newx = strlen(message) + x;
int xx = 0;
char* ret = new char[limit];
char* buf = new char[limit];
char* buf2 = new char[limit];
int kc = readkey();
char k = kc & 0xff;
while((kc >> 8) != KEY_ESC)
{
//can't be \ / ? * " : < > |
if (!(k == '\\' || k == '|' || k == '/' || k == '?' || k == '*' || k == '\"' || k == ':' || k == '<' || k == '>') && keypressed())
{
textout(screen,font,"BLAH",150,150,col);
while(key[kc >> 8]) { poll_keyboard(); }
if ((kc >> 8) == KEY_BACKSPACE)
{
if (strlen(ret) > 0)
{
ret[strlen(ret)-1] = '\0';
xx = newx + 8;
}
for(int p = 0; p < (limit-strlen(ret)); p++)
buf[p] = ' ';
buf[p+1] = '\0';
strcpy(buf2,ret);
strcat(buf2,buf);
textout(screen,font,message,x,y,col);
textout(screen,font,buf2,xx,y,col);
}
else if ((kc >> 8) == KEY_ENTER)
{
delete[] buf;
delete[] buf2;
return ret;
}
else
{
if (strlen(ret) < limit)
{
strcpy(buf2,ret);
strcat(buf2,(const char*)k);
strcpy(ret,buf2);
xx = newx + strlen(ret)*8;
textout(screen,font,ret,xx,y,col);
}
}
}
poll_keyboard();
kc = readkey();
k = kc & 0xff;
}
delete[] ret;
delete[] buf;
delete[] buf2;
return "~";
} |
|
|
Back to top |
|
|
Rainer Deyke Demon Hunter
Joined: 05 Jun 2002 Posts: 672
|
Posted: Fri Jun 04, 2004 9:45 pm Post subject: Re: code snippet - won't stop crashing |
[quote] |
|
Disclaimer: I have never used Allegro, so I may be way off in my comments that refer to Allegro.
Code: | char* dinput(const char* message, int x, int y, int limit, int col) |
Using std::string instead of char* will make life a lot easier for you.
Code: | {
textout(screen, font, message, x, y, col);
int newx = strlen(message) + x; |
'strlen' returns the length of the string in characters, not pixels. If you have a fixed-character-width font, multiply by the character width in pixels. If not, use another approach.
Code: | int xx = 0;
char* ret = new char[limit];
char* buf = new char[limit];
char* buf2 = new char[limit];
int kc = readkey();
char k = kc & 0xff;
while((kc >> 8) != KEY_ESC)
{
//can't be \ / ? * " : < > |
if (!(k == '\\' || k == '|' || k == '/' || k == '?' || k == '*' || k == '\"' || k == ':' || k == '<' || k == '>') && keypressed()) |
There are two things which look funny about the line above. One is that you accept all keys except those listed above, which may include weird keys like F1. The other is that a key may have been pressed or released between your call to 'readkey' and your call to 'keypressed'.
Code: | {
textout(screen,font,"BLAH",150,150,col);
while(key[kc >> 8]) { poll_keyboard(); } |
Here you're waiting for the key to be released? That seems weird. Usually text input responds immediately when a key is pressed, not when it is released.
Code: | if ((kc >> 8) == KEY_BACKSPACE)
{
if (strlen(ret) > 0)
{
ret[strlen(ret)-1] = '\0';
xx = newx + 8; |
If 'strlen(ret)' is 0, 'xx' is not properly initialized.
Code: | }
for(int p = 0; p < (limit-strlen(ret)); p++)
buf[p] = ' '; |
If 'strlen(ret)' is 0, then this overwrites the entire buffer 'buf' with spaces without leaving room for the terminating 0.
When the loop terminates, 'p' is already one past the last character in the buffer that was filled with a space. 'p+1' should be either 'p' or 'p-1'.
Code: | strcpy(buf2,ret);
strcat(buf2,buf);
textout(screen,font,message,x,y,col);
textout(screen,font,buf2,xx,y,col);
}
else if ((kc >> 8) == KEY_ENTER)
{
delete[] buf;
delete[] buf2;
return ret;
}
else
{
if (strlen(ret) < limit)
{
strcpy(buf2,ret);
strcat(buf2,(const char*)k); |
That is just wrong. 'k' is not a string, it's a single character. It is not followed by a terminating 0. I'm guessing that this is the line which causes the crash. The correct way to append a character onto a C-style string is like this:
Code: | int length = strlen(buf2);
buf2[length] = k; // append character
buf2[length + 1] = 0; // append terminating 0 |
Code: | strcpy(ret,buf2);
xx = newx + strlen(ret)*8; |
Why are you adding 'strlen(ret)*8' to 'xx'? Wouldn't that move the string further to the right as it got longer?
Code: | textout(screen,font,ret,xx,y,col);
}
}
}
poll_keyboard(); |
Why are you calling 'poll_keyboard' here, but not before your first call to 'readkey' ?
Code: | kc = readkey();
k = kc & 0xff;
}
delete[] ret;
delete[] buf;
delete[] buf2;
return "~"; |
That return statement is also just plain wrong. If the caller receives the string "~", it won't know if the user actually entered "~" or if the user pressed escape. In the former case, the caller is responsible for deleting the string. In the latter case, the program will crash if the caller tries to delete the string. A better way of indicating that the user pressed escape would be to return a null pointer. Alternately, you could fill the buffer 'ret' with some special value and return that instead of deleting the buffer here. That way the caller is always responsible for deleting the returned buffer, regardless of whether the user entered a string or pressed escape.
|
|
Back to top |
|
|
Ninkazu Demon Hunter
Joined: 08 Aug 2002 Posts: 945 Location: Location:
|
Posted: Fri Jun 04, 2004 11:38 pm Post subject: |
[quote] |
|
Thanks man, I got it working.
|
|
Back to top |
|
|
|
Page 1 of 1 |
All times are GMT
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
|