Notice: Any messages purporting to come from this site telling you that your password has expired, or that you need to "verify" your details, making threats, or asking for money, are
spam. We do not email users with any such messages. If you have lost your password you can obtain a new one by using the
password reset link.
Entire forum
➜ Programming
➜ STL
➜ Columned Displays?
It is now over 60 days since the last post. This thread is closed.
Refresh page
Posted by
| Davion
Canada (10 posts) Bio
|
Date
| Sun 23 Apr 2006 07:15 PM (UTC) |
Message
| Just wondering if you have a good way to column a list? Ie.
[ look] [ find] [ jog] [ jump]
[ scan] [ run] [ dash] [dance]
I've been trying to toy with for_each, but I can't quite figure it out.
Davion | Top |
|
Posted by
| David Haley
USA (3,881 posts) Bio
|
Date
| Reply #1 on Sun 23 Apr 2006 07:31 PM (UTC) |
Message
| What you need to do is first figure out how many columns you will need/have. Then, for each column, you'd figure out what the widest element of that column is. Once you have that maximum width, you can print out each element to fit into that width. I'm not sure if for_each would actually work in this case, since you're not doing the same thing to each element. |
David Haley aka Ksilyan
Head Programmer,
Legends of the Darkstone
http://david.the-haleys.org | Top |
|
Posted by
| Davion
Canada (10 posts) Bio
|
Date
| Reply #2 on Sun 23 Apr 2006 07:52 PM (UTC) |
Message
| *nodnod* Thanks! Actually kept toying with it after I posted and just finished :) Here's what I go
class cmdDisplay
{ int iLength;
String str;
public:
cmdDisplay() : iLength(0) { str.Empty(); };
void operator()(CmdType *cmmd )
{ iLength++;
cmmd->Display(str, iLength);
}
void SendCmds(Entity *en)
{ en->Send("%s", *str);
}
};
void Interpreter::doCmdList(Entity *en, String &arguments)
{ for_each(en->interp->cmdList.begin(),
en->interp->cmdList.end(),
cmdDisplay() ).SendCmds(en);
return;
}
void CmdType::Display(String &rhs, int length)
{ char buf[10000];
sprintf(buf, "[%-10s]", &(*name));
rhs << buf;
if( !(length % 4 ) ) rhs << "\n\r";
}
Excuse the horrible hacking of Display :) I haven't quite finished my string lib, so it's a bit... strange atm :). Seems to work very nicely though!
Davion | Top |
|
Posted by
| David Haley
USA (3,881 posts) Bio
|
Date
| Reply #3 on Sun 23 Apr 2006 08:05 PM (UTC) |
Message
| Oh yeah. I forgot about function objects and how they let you do the "same" operation every time. *bonk self* I'm curious; have you tested it and is it working? Looks good to me... Of course, you're giving the same width to every column, which makes things easier. |
David Haley aka Ksilyan
Head Programmer,
Legends of the Darkstone
http://david.the-haleys.org | Top |
|
Posted by
| Davion
Canada (10 posts) Bio
|
Date
| Reply #4 on Sun 23 Apr 2006 08:21 PM (UTC) |
Message
| Looks like it! The most any of my interpreters have is 4 commands, so I dropped columning down to two, and it worked fine!
command
[create ][setpasswd ]
[login ][command ]
>
The MudObject stuff in one of the prior threads helped a lot!
Davion | Top |
|
Posted by
| David Haley
USA (3,881 posts) Bio
|
Date
| Reply #5 on Sun 23 Apr 2006 08:28 PM (UTC) |
Message
| Very good. The STL is really quite amazing when you look at it like this. Look at what you were able to do in so relatively few lines of code. Then think how much it would have been in straight C, and how less elegant it would have been. Bah! :-)
And yes, Nick's guides are excellent; very useful material. Some of them are for the intermediate-level coder, but if you know enough to understand the guides the potential for useful learning is immense. |
David Haley aka Ksilyan
Head Programmer,
Legends of the Darkstone
http://david.the-haleys.org | Top |
|
Posted by
| Davion
Canada (10 posts) Bio
|
Date
| Reply #6 on Sun 23 Apr 2006 09:19 PM (UTC) Amended on Sun 23 Apr 2006 09:37 PM (UTC) by Davion
|
Message
| Look at what you were able to do in so relatively few lines of code.
This statement really nudged me. Soo! I went for it
void doDisplay(CHAR_DATA *ch, char *argument)
{ std::list<CmdType *>::iterator i;
char buf[MSL];
for(int n = 0, i = ch->interp->begin(); i != ch->interp->end() ; ++i, ++n)
{ sprintf(buf, "[%-10s]", (*i)->name);
send_to_char(buf,ch);
if(!(n % 4) )
send_to_char("\n\r", ch);
}
}
Just typed that out dunno if it compiles, but that does the same thing in like 1/4 the lines of code. So. I figured, if I'm going to use this, I might as well make it worth while. I switched up my display function to->
template <class T>
class DisplayList
{ int iLength;
String str;
public:
DisplayList() : iLength(0) { str.Empty(); };
void operator()(T *node )
{ iLength++;
node->Display(str, iLength);
}
void Send(Entity *en)
{ en->Send("%s", *str);
}
};
Now, as long as the type class has a Display() method, it will display it. I understand it's dangerous to assume Display exists, but I don't think I'll be using this on classes where it lacks a Display method. This now seems a bit more practical, rather than writing a new one for each different kind of node.
Davion
| Top |
|
Posted by
| Nick Gammon
Australia (23,046 posts) Bio
Forum Administrator |
Date
| Reply #7 on Sun 23 Apr 2006 10:11 PM (UTC) |
Message
| Very nice!
Strictly speaking, in this line:
cmdDisplay() : iLength(0) { str.Empty(); };
You don't need to do "str.Empty();", because when you define:
String str;
... the constructor is called which I assume initialises it to an empty string (it does for the string class, but you are using String).
However you are correct in initializing iLength because that is a "raw integer" (not a class) and hence is not initialized.
|
- Nick Gammon
www.gammon.com.au, www.mushclient.com | Top |
|
Posted by
| David Haley
USA (3,881 posts) Bio
|
Date
| Reply #8 on Mon 24 Apr 2006 01:44 AM (UTC) |
Message
| I think I read somewhere that some implementations actually will initialize all member variables, including primitives like integers, when you call the new operator. After all, by definition, when you 'new' something, it will initialize all objects in there; I think somebody took that a step further and had it initialize the primitives as well. Since the default constructor for integers is zero, you'd end up with zeroes.
But that's probably non-standard behavior, so don't rely on it... :)
Quote: I understand it's dangerous to assume Display exists, but I don't think I'll be using this on classes where it lacks a Display method Oh, don't worry about that... the compiler will happily barf at you if you try to. :P |
David Haley aka Ksilyan
Head Programmer,
Legends of the Darkstone
http://david.the-haleys.org | Top |
|
Posted by
| Davion
Canada (10 posts) Bio
|
Date
| Reply #9 on Mon 24 Apr 2006 01:36 PM (UTC) |
Message
| I think I read somewhere that some implementations actually will initialize all member variables, including primitives like integers, when you call the new operator. After all, by definition, when you 'new' something, it will initialize all objects in there; I think somebody took that a step further and had it initialize the primitives as well.
Never thought of that.
#include <iostream>
class Foo
{ public:
int bar;
Foo(){}
};
int main()
{ int i;
Foo boo;
std::cout << boo.bar << std::endl << i << std::endl;
return -1;
}
Output
0
1073831104
Seems all those initializers are redundant! Thanks!
Davion | Top |
|
The dates and times for posts above are shown in Universal Co-ordinated Time (UTC).
To show them in your local time you can join the forum, and then set the 'time correction' field in your profile to the number of hours difference between your location and UTC time.
26,784 views.
It is now over 60 days since the last post. This thread is closed.
Refresh page
top