JohnnyStarr
Wizard


Group: Members
Posts: 953
Joined: Feb 14, 2009
|
#1 id:44999 Posted Apr 8, 2010, 7:54 pm
|
I'm taking the idea of fprint_to_char(), but was wanting to have the std::string equivalent.
This doesn't work:
Code (C++): 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 |
// send()
// can send formatted or unformatted strings to character.
void Character::send(std::string s, ...)
{
const char *fmt = s.c_str();
char buf [MAX_STRING_LENGTH];
va_list args;
va_start (args, fmt);
vsprintf (buf, fmt, args);
va_end (args);
Server::instance()->sendCharacter(buf, this);
}
|
You cant send a const (fmt) into vsprintf().
I was hoping there would be a c++ algorithm that does something similar to C's <stdarg.h>
This is just kind of a wrapper for const char* fmt right now.
If there's a quick fix you might know of, I'll gladly take it, and put this off until I'm more comfortable with std strings.
EDIT:
I'm sure the question you might have is: "Why not just use char*?"
Well, the answer is: I guess I don't really have one. I just figured it might be a good idea. I think that it will make
customization like do_score() a breeze.
|
Last edited Apr 8, 2010, 8:05 pm by JohnnyStarr
|
|
JohnnyStarr
Wizard


Group: Members
Posts: 953
Joined: Feb 14, 2009
|
#2 id:45002 Posted Apr 8, 2010, 8:57 pm
|
I'll answer my own question:
I'm planning on keeping my send( const char* fmt, ... )
But i'm going to add Character::stream( ostringstream& stm)
So far it's allowed me to do some pretty cool stuff.
Gives it a Ruby feel:
Code (C++): 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 |
void do_test( Character *ch, char *argument )
{
std::ostringstream buf;
buf << "Hi, my name is " << ch->name << << "\r\n";
buf << "I am level: " << ch->level << << "\r\n";
buf << "The first item in my inventory is " <<
(ch->carrying ? ch->carrying->short_desc : "(nothing)") << "\r\n";
ch->stream(buf);
}
// in character.cpp
void Character::stream(std::ostringstream &stm)
{
send(stm.str().c_str());
}
|
Anyway, I know this is probably not new to anyone else, but it helps a ton.
|
Last edited Apr 8, 2010, 9:22 pm by JohnnyStarr
|
|
|
|
quixadhal
Wizard


Group: Members
Posts: 1,815
Joined: Oct 17, 2007
|
#4 id:45006 Posted Apr 9, 2010, 12:46 am
|
Actually, why not just go all the way and have Character inherit ostringstream? That way you could treat the character itself as a stream object.
Code (text): 1
2
3 | ch << "This is a silly message\r\n"; |
|
......................... 
|
|
Kaz
Conjurer


Group: Members
Posts: 125
Joined: Oct 31, 2009
|
#5 id:45016 Posted Apr 9, 2010, 8:29 am
|
Here is some compiled and tested code that you should be able to manipulate to your needs. Personally, I just use Boost.Format.
Code (text): 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 | #include <string>
#include <iostream>
#include <cstdarg>
#include <cstdio>
using namespace std;
void string_printf(string const &str, ...)
{
va_list args;
char buf[1024];
char const *fmt = str.c_str();
va_start(args, str);
vsprintf(buf, fmt, args);
va_end(args);
cout << buf << endl;
}
int main()
{
string blah = "blah %s foo %d bar %s";
string_printf(blah, "ONE", 2, "THREE");
}
|
|
|
|
JohnnyStarr
Wizard


Group: Members
Posts: 953
Joined: Feb 14, 2009
|
#6 id:45023 Posted Apr 9, 2010, 12:17 pm
|
@quix: That just seems wacky to me, but good to know you can do that.
I actually went a different route. I forgot about method overloading:
Code (c++): 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 |
// can send formatted or unformatted strings to character.
void Character::send(const char *fmt, ...)
{
// cast const to non const to accommodate const and non const arguments.
char *fmt2 = (char*) fmt;
char buf [MAX_STRING_LENGTH];
va_list args;
va_start (args, fmt2);
vsprintf (buf, fmt2, args);
va_end (args);
Server::instance()->sendCharacter(buf, this);
}
void Character::send(std::ostringstream &stm)
{
send(stm.str().c_str());
}
void Character::send(std::string &str)
{
send(str.c_str());
}
|
This way you can send whatever makes most sense at the time.
|
|
|
Kayle
Wizard


Group: Members
Posts: 1,253
Joined: Nov 27, 2006
|
#7 id:45024 Posted Apr 9, 2010, 12:20 pm
|
Why would you cast a const char* to char*? That doesn't make any sense to me.
|
......................... Owner/Coder -- Malevolent Whispers -- Development Phase - Not accepting players
Coder -- Star Wars: The Sith Wars -- Open Alpha - Players Welcome - Full System Re-writes Imminent.
FUSS Project Team Lead -- SmaugMuds.Org - The Smaug MUDs Community Center
I3 Contact: Kayle@SithWars
|
|
|
|
Sharmair
Sorcerer


Group: Members
Posts: 261
Joined: Nov 9, 2008
|
#9 id:45028 Posted Apr 9, 2010, 12:40 pm
|
That 2nd argument to va_start should be the last required parameter in the function,
fmt in that case not fmt2. This was also a problem with the first code that passed
the string. Though in that case I would have not passed a string, but a reference
to a string (probably a constant reference actually). I also have no idea why you
would even have fmt2 in that last code, or why you would cast it.
|
|
|
JohnnyStarr
Wizard


Group: Members
Posts: 953
Joined: Feb 14, 2009
|
#10 id:45029 Posted Apr 9, 2010, 12:44 pm
|
The problem is you cant convert a string or ostringstream to non const char*.
The send routine is in fact needing to modify the input because it gives an error on vsprintf if the char* fmt is const
it will not let you modify the original text, which is kind of the point right? Don't you want to alter the input text
because it will be changed from "%s is a string, and %d is a number." to "France is a string, and 34 is a number."
I totally get that you shouldn't be doing this if you can avoid it, so what would you suggest?
|
|
|
|
|
JohnnyStarr
Wizard


Group: Members
Posts: 953
Joined: Feb 14, 2009
|
#12 id:45031 Posted Apr 9, 2010, 12:49 pm
|
Ok, nevermind i get it. I changed the cast and got rid of the fmt2 and it works
just fine. so i guess i must have missed something. I get what you mean about not altering the fmt string too.
|
|
|
Sharmair
Sorcerer


Group: Members
Posts: 261
Joined: Nov 9, 2008
|
#13 id:45032 Posted Apr 9, 2010, 12:59 pm
|
The 2nd (format) argument to vfprintf should be declared as a const char*. If you
are really getting an error about that, I would make sure your MUD code is not declaring
vfprintf instead of a system header (and doing it wrong).
|
|
|