string::resize and string::max_size
julian_boolean

Does anyone know how to use either of this in a function to set the max length of a string?

Thomas Fjellstrom

I don't think you can besides subclassing and implementing max_size yourself. And thats only if the base class bothers caring about max_size.

TeamTerradactyl
Thomas Fjellstrom

Well, I guess it depends if he wants a HARD max limit, or just wants to reserve some space.

julian_boolean

If reserve() works by crashing the program, it works pretty good.

void textfield::set_length(int l)
{
  str.reserve(l);
}

What am I doing wrong. :P I figured I might have to do it myself, but can't think of how. Maybe by using clear_keybuf(), but that thing is just a pain in the ass.

23yrold3yrold
Quote:

What am I doing wrong.

Probably using it at all. :) It's not like it affects the string's behavior in any way.

julian_boolean

What I had before was:

void textfield::set_length(int l)
{
  length = l

  if(str.length() >= length)
  {
    clear_keybuf();
  }
}

It worked up until it got to what was in int l.

Matthew Dalrymple

reserve() is meant for situations where you know the total size of the STL object you are working with, and in the process of getting to that point you would normally be reallocating memory lots of times. For example: concatenating a string one letter at a time when you know the word is going to be 15 letters long. You would use reserve so it would allocate the memory all at one time. At least that is what I have taken from it.

Quote:

It worked up until it got to what was in int l.

So do you mean doing this would fix it:

if(str.length() > length)

I'd like to see more code to see why reserve is crashing. The full class and how it is being used would be nice. 8-)

julian_boolean

http://www.allegro.cc/forums/thread/589667 I think I have it posted in there.

Matthew Dalrymple

Alright, well did my little fix make your program work correctly? (The greaterthan or equals to just a greaterthan)

I didn't see much code in that post but oh well.

julian_boolean

I really don't know what I'm doing with this. All the clear_keybuf is doing is preventing me from inputting, indefinitely (can't backspace.) I was trying to find another way to do it without using it.

Matthew Dalrymple

Maybe structure this like so... (this is more pseudo-code then anything)

1string input;
2const int MAX_INPUT = 1024;
3while(!key[KEY_ENTER] || BUTTON_OK.isPressed())
4{
5 if(input.size() < MAX_INPUT)
6 {
7 // never really worked with this yet so you fill in the syntax
8 // also need to check to see if the key is a viewable character
9 input += read_key();
10 }
11 if(key[KEY_BACKSPACE])
12 {
13 // string doesn't have a pop method so you're going to have to create this on your own
14 input.pop();
15 }
16}

julian_boolean

Ok! This sorta works..

1void textfield::set_length(int l)
2{
3 length = l
4 
5 if(edittext.length() >= length)
6 {
7 clear_keybuf();
8 }
9}
10 
11void textfield::poll()
12{
13 if(is_active)
14 {
15 while(keypressed())
16 {
17 int newkey = readkey();
18 char ASCII = newkey & 0xff;
19 char scancode = newkey >> 8;
20 
21 if(ASCII >= 32 && ASCII <= 126)
22 {
23 if(insert || iter == edittext.end())
24 iter = edittext.insert(iter, ASCII);
25
26 else
27 edittext.replace(caret, 1, 1, ASCII);
28 caret++;
29 iter++;
30 }
31 
32 else
33 switch(scancode)
34 {
35 case KEY_DEL:
36 if(iter != edittext.end()) iter = edittext.erase(iter);
37 break;
38 
39 case KEY_BACKSPACE:
40 if(iter != edittext.begin())
41 {
42 caret--;
43 iter--;
44 iter = edittext.erase(iter);
45 if(edittext.length() >= length) readkey(); // <- This
46 }break;
47
48 case KEY_RIGHT:
49 if(iter != edittext.end()) caret++, iter++;
50 break;
51
52 case KEY_LEFT:
53 if(iter != edittext.begin()) caret--, iter--;
54 break;
55
56 case KEY_INSERT:
57 insert = !insert;
58 break;
59 
60 default:
61 break;
62 }
63 }
64 }
65}

For the most part, it seems a little buggy though.

Matthew Dalrymple

What specifically seems to be buggy with it?

For future reference

else
  edittext.replace(caret, 1, 1, ASCII);
  caret++;
  iter++;

I believe that else statement will only work for the next line down without braces. If thats true then you should un-indent those next two lines for better readability.

If you meant for all three of those to statements to go only on the else case then use the {}'s.

julian_boolean

I didn't write the code for text input but it seems to work well, 100 x better then gstream anyway.

It's kinda hard to explain, once you go beyond the max amount of characters it looks like it's laggy almost, but you can still backspace.. It's just difficult sometimes (have to hold in backspace or press it a bunch of times.)

Is there anyway to say something like:

if(str.length() >= length)
{
  clear_keybuf();
}

else
  do_not_clear_keybuf();

Kauhiz

Err... It doesn't clear the keybuffer unless you explicitly tell it to :P. What do you mean by do_not_clear_keybuf()? A function that does nothing?

Quote:

It's just difficult sometimes (have to hold in backspace or press it a bunch of times.)

I haven't looked at your code at all, but try it without the call to clear_keybuf().

julian_boolean

Well, just something I can use to make it stop clear_keybuf(). I tried to find different things but nothing seems to work very well.. Someone suggested just to make the text code stop polling whenever you reach the max text limit, which I CAN do though I just want to find a different way.

Kauhiz
Quote:

make it stop clear_keybuf()

Don't call clear_keybuf(), maybe?

julian_boolean

How can I prevent the user from inputting text beyond the max limit then?

Kauhiz

If the max limit has been reached, ignore them.

while(keypressed() && text.length() < max_length)
{
  // find out what key the user pressed
}

Matthew Dalrymple
julian_boolean said:

How can I prevent the user from inputting text beyond the max limit then?

Did you look at my pseudo-code? It will just skip the line of reading key input if the max has been reached. But it still allows for key input.

julian_boolean

I didn't really know what you mean't by a pop function or what it does exactly.

Edit:

while(keypressed() && text.length() < max_length)
{
  // find out what key the user pressed
}

I was thinking that awhile ago, but wouldn't that boot me out of the while loop? How would I be able to backspace?

Kauhiz

Ok, so put it in an if statement inside the while loop, and put the backspace check outside that if statement. Think before you post! ;)

julian_boolean

Sorry :P sometimes my head isn't screwed on properly. That seems to work very, VERY nicely.. I guess as long as I'm not getting any errors, and as long as the program isn't acting funky and/or crashing it'll be fine.

Matthew Dalrymple
Quote:

I didn't really know what you mean't by a pop function

It's just a term to refer to removing/returning something on the end of a stack/queue.

julian_boolean

While I'm still on sorta the same subject, the last thing I wanted to do was make a function that can censor input by just replacing it with some kinda symbol like "*" or "#".

1 
2 if(ASCII >= 32 && ASCII <= 126 && edittext.length() < max_length)
3 {
4 if(insert || iter == edittext.end())
5 {
6 if(!censored)
7 {
8 iter = edittext.insert(iter, ASCII);
9 }
10 
11 else
12 iter = edittext.something..
13 }
14
15 else
16 edittext.replace(caret, 1, 1, ASCII);
17 caret++;
18 iter++;
19 }

For that I'm guessing I should use replace?

Matthew Dalrymple

Yes you would need to use replace, unless you are using this for a password and you are wanting *'s to show up instead of the actually text. Is that what you mean?

julian_boolean

Unless? It will be used for passwords, is there something else already made for that?

Matthew Dalrymple

There is a different method. Where you are actually drawing the text just a number of *'s related to the size of the text they have entered. Keeping it synchronized with the actually amount in it of course (factoring in backspace and what not).

EDIT: If you use replace you will actually be overwriting what is in the string. I thought you might be using this to replace cuss words and such with !@#$%^&*'s.

julian_boolean

What is this method? Overwriting the input as * works too doesn't it?

Well for filtering certain words, I figure that would have to be a seperate function on it's own.

Matthew Dalrymple
Quote:

What is this method? Overwriting the input as * works too doesn't it?

You can go with this method, but when you get to the point of trying to do something with the password they entered in all you are going to see is "*********" The star's are meant for people around you not to see your password. If you overwrite their password with the actual stars then their password then becomes stars. Everyone's password will be almost the same, just varying lengths of stars.

What you want to accomplish is keeping their password in the string, then when it comes time to draw their password to the screen you just draw the number of stars that is equivalent to the number of characters in their password.

Type in: zomgtheholyinterents
They see: ********************

If I'm correct with your method their password will be "********************" instead of "zomgtheholyinterents"

Now you can keep your method as long as you have another string to store their actual password and one string to store whats actually being drawn to the screen. My method reduces the number of strings you need.

julian_boolean

I never actually thought of that.. Damn. Well I guess it doesn't really matter if I use an extra string to do that, it's easier for me anyway since I don't know any other way to go about doing it.

Matthew Dalrymple

Yeah I thought I'd stop you before you ran into that run-time. If you show me a clip of your drawing method I can help you draw it without using another string, but there is nothing wrong in using another string if that's what works for you.

julian_boolean

Here's what my rough guess at what I think it would look like:

1if(ASCII >= 32 && ASCII <= 126 && edittext.length() || editcensor.length() < max_length)
2{
3 if(insert || iter == edittext.end())
4 {
5 if(!censored)
6 {
7 iter = edittext.insert(iter, ASCII);
8 }
9 
10 else
11 iter = editcensor.something..
12 }
13 
14
15 else
16 edittext.replace(caret, 1, 1, ASCII);
17 caret++;
18 iter++;
19}
20 
21if(!censored)
22 textout_ex(dbuffer, font, edittext.c_str(), textx, texty, WHITE, -1);
23 
24else
25 textout_ex(dbuffer, font, edittcensor.c_str(), textx, texty, WHITE, -1);

Edit:

I noticed that if that even worked, it would be only doing the input for editcensor..

Matthew Dalrymple

Just remove the replaces and do this...:

if(!censored)
  textout_ex(dbuffer, font, edittext.c_str(), textx, texty, WHITE, -1);
else
{
  string censor;
  for(int i = 0; i < edittext.length(); i++)
    censor += "*";
  textout_ex(dbuffer, font, censor.c_str(), textx, texty, WHITE, -1);
}

julian_boolean

That seems to work, sorta. When I input the text it will show up as *'s, but every keystroke seems to double the amount. In other words, if I type in "test" the "t" would show up as 1 *, the "e" would show up as 2 *'s, etc.

Maybe saying "censor = edittext.length();" or something like that might work.. Trying that now. :P

I was fooling around with it again and now a single keystroke makes it automatically print out an ass load of *'s.. I'm sure the problem is very simple, still picking at it..

Matthew Dalrymple

Oh I'm sorry, here is the fix:

if(!censored)
  textout_ex(dbuffer, font, edittext.c_str(), textx, texty, WHITE, -1);
else
{
  string censor;
  for(int i = 0; i < edittext.length(); i++)
    censor += "*";
  textout_ex(dbuffer, font, censor.c_str(), textx, texty, WHITE, -1);
  /*    / THIS IS THE FIX /    */
  //censor.erase();
  // EDIT:
  censor.clear();
}

The problem was that censor was not erasing, so it would keep re stacking the edittext onto itself.

julian_boolean

You are not a man but a god! Hehe that works perfectly, one question though:

  textout_ex(dbuffer, font, censor.c_str(), textx, texty, WHITE, -1);
  censor.erase();
  censor.clear();

What exactly is the difference between erase and clear?

Matthew Dalrymple

I had to go double check myself after I posted on http://www.cppreference.com
erase takes parameters, so you can erase a specific field while clear() will erase the whole string.

Quote:

You are not a man but a god!

Nah, it's just problems that I've ran into before so I know exactly what was going on. I mean.. yes I am a god.

julian_boolean

Hehe! I just wanted to thank everyone for helping out me so much, especially Matthew. You've all been great, thanks again! :)

Matthew Dalrymple

FYI: This forum has a new feature that when the creator of the topic posts you can check a box that says something around the lines of "My question was answered fully" then you give props so people know your question has been answered. But a last post like yours is good too :D

23yrold3yrold
Quote:

But a last post like yours is good too :D

No. I demand cookies.

PS: That checkbox doesn't appear unless you create the thread with one in the first place.

julian_boolean

For future reference, how can I do this (is it the thing that says "Classification"?) Thanks. ;)

Tobias Dammers
if(!censored)
  textout_ex(dbuffer, font, edittext.c_str(), textx, texty, WHITE, -1);
else
{
  string censor('*', edittext.length()); // initialize to a given number of asterisks
  textout_ex(dbuffer, font, censor.c_str(), textx, texty, WHITE, -1);
// no need to clear: censor will clear itself when it goes out of scope, since it's non-static
}

Matthew Dalrymple
Quote:

For future reference, how can I do this (is it the thing that says "Classification"?) Thanks. ;)

Yeah, normally choose "A question seeking a specific answer."

To Tobias:
With my example that's what should be happening but I think he might have made it a member variable, so clearing the string was appropriate. But I do like your method.

Thread #589861. Printed from Allegro.cc