09 Apr, 2010, JohnnyStarr wrote in the 1st comment:
Votes: 0
I'm taking the idea of fprint_to_char(), but was wanting to have the std::string equivalent.
This doesn't work:

// 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.
09 Apr, 2010, JohnnyStarr wrote in the 2nd comment:
Votes: 0
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:

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.
09 Apr, 2010, kiasyn wrote in the 3rd comment:
Votes: 0
I would not name it stream, as it could conflict if you ever use the stream class?
09 Apr, 2010, quixadhal wrote in the 4th comment:
Votes: 0
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.

ch << "This is a silly message\r\n";
09 Apr, 2010, Kaz wrote in the 5th comment:
Votes: 0
Here is some compiled and tested code that you should be able to manipulate to your needs. Personally, I just use Boost.Format.

#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");
}
09 Apr, 2010, JohnnyStarr wrote in the 6th comment:
Votes: 0
@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:

// 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.
09 Apr, 2010, Kayle wrote in the 7th comment:
Votes: 0
Why would you cast a const char* to char*? That doesn't make any sense to me.
09 Apr, 2010, David Haley wrote in the 8th comment:
Votes: 0
It doesn't make sense and is actually useless. A non-const argument will be converted to const by the compiler. (The word "conversion" is slightly misleading, because nothing is being actually changed.) So, the const version of the function is already accommodating both const and non-const arguments.

It is in fact dangerous because now you're opening the door to modifying the input by accident which is something you really don't want to do.
09 Apr, 2010, Sharmair wrote in the 9th comment:
Votes: 0
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.
09 Apr, 2010, JohnnyStarr wrote in the 10th comment:
Votes: 0
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?
09 Apr, 2010, David Haley wrote in the 11th comment:
Votes: 0
No you don't want to write into your format buffer. You write into an output buffer. (But that's what you're doing. So I'm confused about why you talk of writing into the input text buffer.)
09 Apr, 2010, JohnnyStarr wrote in the 12th comment:
Votes: 0
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.
09 Apr, 2010, Sharmair wrote in the 13th comment:
Votes: 0
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).
0.0/13