Archived

This topic is now archived and is closed to further replies.

Formatted Strings and Ellipsis

This topic is 5017 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Two questions - 1) Is there is a function similar to the sprintf () C function which will work with std::string? 2) Is it possible to pass ellipsis from one function into another? e.g.
void CLog::LogMessage (enum eMessageType Type, std:string sMessage, ...)
{
	// Format according to the message type
	...

	// Write string to file
	WriteString (sMessage, ...);	// HERE: Pass the parameter list on to the WriteString function
}
 
Thanks!

Share this post


Link to post
Share on other sites
1) Yes, sprintf(). Remember std::string has a c_str() member function.

2) Yes, but only for certain functions. Try looking up vsprintf().

Share this post


Link to post
Share on other sites
I meant using an std::string like...

std::string sTemp;
sprintf (sTemp, "Number = %i", 123);

I realise that won''t work, (and nor will using c_str ()) but I meant using std::string as the buffer, not the format string.

Share this post


Link to post
Share on other sites
OK, how do use format a string to a std::stringstream?

EDIT:
Bear in mind that I want to using formatting with a va_list, like vsprintf.

[edited by - Barguast on April 21, 2004 9:21:19 AM]

Share this post


Link to post
Share on other sites

#include <sstream>
#include <string>
#include <iostream>

int main(int argc, char *argv[])
{
std::stringstream ss;
std::string n = "other text";

ss << "Some text " << 12 << n;
std::cout << ss.str();

return 0;
}


like this !
I think you can figure out how to do it with a va_list

Hope it helps !
Matt

[edited by - lemurion on April 21, 2004 9:41:30 AM]

Share this post


Link to post
Share on other sites
Be aware that you''re mixing C and C++ in a weird way. If you went the straight C approach, you can do something like this:
void CLog::LogMessage(enum eMessageType Type, char *szMessage, ...)
{
char szBuffer[1024]; // Make this large enough to hold anything you''ll log


va_list argList;

va_start(argList, szString);
vsprintf(szBuffer, szString, argList); // Basically, take the (char *szMessage, ...) and sprintf it into szBuffer

va_end(argList);

WriteString(szBuffer);
}


I don''t recommend mixing std::string with the C printf family of functions. Choose either C or C++.

Share this post


Link to post
Share on other sites
Depending on how you feel about such things and the requirements of your project you might want to try boost:format.


[edited by - mauman on April 21, 2004 10:10:50 AM]

Share this post


Link to post
Share on other sites
quote:
Original post by lemurion

#include <sstream>
#include <string>
#include <iostream>

int main(int argc, char *argv[])
{
std::stringstream ss;
std::string n = "other text";

ss << "Some text " << 12 << n;
std::cout << ss.str();

return 0;
}


like this !
I think you can figure out how to do it with a va_list

Hope it helps !
Matt

[edited by - lemurion on April 21, 2004 9:41:30 AM]


erm, well, no. I''ve only just started working with va_list, and I''ve got no idea how this''d work! Thanks for the example, but could anyone demomstrate how I might use a va_list in this example?

Thanks

Share this post


Link to post
Share on other sites
quote:
Original post by Barguast
erm, well, no. I''ve only just started working with va_list, and I''ve got no idea how this''d work! Thanks for the example, but could anyone demomstrate how I might use a va_list in this example?

Thanks



I just did. Did you not read my post above?

Share this post


Link to post
Share on other sites
I know how to use va_list with vsprintf, but not in the code lemurion posted (the one I referred to). Although it''d work, I''m trying not to use a huge C-style buffer like you suggested. I''ve used these in the past and am trying to move away from ''em.

Share this post


Link to post
Share on other sites
OK, I didn''t want to use boost because... ... well, I just didn''t want to!

I''ve tried coding my own and it seems to do the trick (for integers and strings at least). Any comments would be great:

string Format (const string &sFormat, va_list Params)
{
ostringstream sStream;

int iStartPos, iPos = 0;
while (iPos != -1)
{
iStartPos = iPos;

// Search for parameter insertion point
iPos = sFormat.find (''%'', iStartPos);

if (iPos == string::npos)
{
sStream << sFormat.substr (iStartPos, string::npos).c_str ();
}
else
{
if (iPos < sFormat.size ())
{
sStream << sFormat.substr (iStartPos, iPos - iStartPos);

// Get the Parameter Type
char chParam = sFormat.c_str () [iPos + 1];

// Insert the Parameter
switch (chParam)
{
case ''%'':
sStream << ''%'';
break;
case ''i'':
sStream << (int) va_arg (Params, int);
break;
case ''s'':
sStream << (char *) va_arg (Params, char *);
break;
}

// Skip past the Parameter insertion point
iPos += 2;
}
}
}

// Return the String
return sStream.str ();
}

Share this post


Link to post
Share on other sites
Aside from the obvious type-safety issues, the very same that do plague the printf family of functions, aside from the lack of support for printing user-defined types, a casual reading of the function indicates that it should work. edit: oops, no, it will break if the last character in the string is a '%'.

I do second VolkerG's opinion that boost::format is a better solution, though. Why precisely don't you want to use it?



[edited by - Fruny on April 23, 2004 11:28:29 AM]

Share this post


Link to post
Share on other sites
quote:
Original post by Barguast
I know how to use va_list with vsprintf, but not in the code lemurion posted (the one I referred to). Although it''d work, I''m trying not to use a huge C-style buffer like you suggested. I''ve used these in the past and am trying to move away from ''em.


And how is using a stringstream not using a huge buffer? While creating the string via the stringstream, memory probably gets reallocated at least half a dozen times as the string grows. That''s much slower than just using a larger static buffer.

Share this post


Link to post
Share on other sites