Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > A better way of formatting strings?

Reply
Thread Tools

A better way of formatting strings?

 
 
Ricky65
Guest
Posts: n/a
 
      03-24-2011
I was thinking about string formatting after reading this article by
Herb Sutter here:
http://www.gotw.ca/publications/mill19.htm

I thought to myself "Why haven't they overloaded the << operator for
the basic_string class?" like with the iostream. I don't think I'm the
first to have thought of this. I assume performance problems are the
reason this is not done.

This would eliminate the need to make a temporary variable to hold the
formatted data like a stringstream does and the problems with the
sprintf family. I know a lot of people shun stringstreams because they
are unacceptably slow in some cases.

For example, we could do something like this:
int cat_len = 120;
int mouse_len = 29;

std::string myformattedstring << "The cat is " << a << "cm tall and
the mouse is " << b << "cm tall.";

As you can see, this would format directly to the string. This would
be both type safe and length safe and the programmer wouldn't have to
allocate a temporary variable for a stream. However, I'm not sure how
efficient it would be. I'm intrigued to know if this can be done and
and if not, the reasons why.

Thanks

Ricky Marcangelo
 
Reply With Quote
 
 
 
 
Ricky65
Guest
Posts: n/a
 
      03-24-2011
sorry, brainstorm. a and b should be cat_len and mouse_len
respectively.
 
Reply With Quote
 
 
 
 
Victor Bazarov
Guest
Posts: n/a
 
      03-24-2011
On 3/24/2011 10:38 AM, Ricky65 wrote:
> I was thinking about string formatting after reading this article by
> Herb Sutter here:
> http://www.gotw.ca/publications/mill19.htm
>
> I thought to myself "Why haven't they overloaded the<< operator for
> the basic_string class?" like with the iostream. I don't think I'm the
> first to have thought of this. I assume performance problems are the
> reason this is not done.
>
> This would eliminate the need to make a temporary variable to hold the
> formatted data like a stringstream does and the problems with the
> sprintf family. I know a lot of people shun stringstreams because they
> are unacceptably slow in some cases.
>
> For example, we could do something like this:
> int cat_len = 120;
> int mouse_len = 29;
>
> std::string myformattedstring<< "The cat is "<< a<< "cm tall and
> the mouse is "<< b<< "cm tall.";


This syntax is invalid. You either declare an object (and initialize
it) or manipulate it using operator<<. You can't do both in the same
statement.

> As you can see, this would format directly to the string. This would
> be both type safe and length safe and the programmer wouldn't have to
> allocate a temporary variable for a stream. However, I'm not sure how
> efficient it would be. I'm intrigued to know if this can be done and
> and if not, the reasons why.


It cannot, see above.

V
--
I do not respond to top-posted replies, please don't ask
 
Reply With Quote
 
Ricky65
Guest
Posts: n/a
 
      03-24-2011
On Mar 24, 2:52*pm, Victor Bazarov <v.baza...@comcast.invalid> wrote:
> On 3/24/2011 10:38 AM, Ricky65 wrote:
>
>
>
>
>
>
>
>
>
> > I was thinking about string formatting after reading this article by
> > Herb Sutter here:
> >http://www.gotw.ca/publications/mill19.htm

>
> > I thought to myself "Why haven't they overloaded the<< *operator for
> > the basic_string class?" like with the iostream. I don't think I'm the
> > first to have thought of this. I assume performance problems are the
> > reason this is not done.

>
> > This would eliminate the need to make a temporary variable to hold the
> > formatted data like a stringstream does and the problems with the
> > sprintf family. I know a lot of people shun stringstreams because they
> > are unacceptably slow in some cases.

>
> > For example, we could do something like this:
> > int cat_len = 120;
> > int mouse_len = 29;

>
> > std::string myformattedstring<< *"The cat is "<< *a<< *"cm tall and
> > the mouse is "<< *b<< *"cm tall.";

>
> This syntax is invalid. *You either declare an object (and initialize
> it) or manipulate it using operator<<. *You can't do both in the same
> statement.
>
> > As you can see, this would format directly to the string. This would
> > be both type safe and length safe and the programmer wouldn't have to
> > allocate a temporary variable for a stream. However, I'm not sure how
> > efficient it would be. I'm intrigued to know if this can be done and
> > and if not, the reasons why.

>
> It cannot, see above.
>
> V
> --
> I do not respond to top-posted replies, please don't ask


Sorry, I meant

std::string myformattedstring;

myformattedstring << "The cat is " << a << "cm tall and
the mouse is " << b << "cm tall.";
 
Reply With Quote
 
Michael Doubez
Guest
Posts: n/a
 
      03-24-2011
On 24 mar, 15:38, Ricky65 <ricky...@hotmail.com> wrote:
> I was thinking about string formatting after reading this article by
> Herb Sutter here:http://www.gotw.ca/publications/mill19.htm
>
> I thought to myself "Why haven't they overloaded the << operator for
> the basic_string class?" like with the iostream.


Who is "they" ? The standard committee ?

> I don't think I'm the
> first to have thought of this. I assume performance problems are the
> reason this is not done.


Doing so would shun formating facilities.

The language definition is geared toward general case. If you have
specific needs, you are expected to roll your own. This avoid
cluttering the standard with use cases that you can recode or that
libraries can provide.

> This would eliminate the need to make a temporary variable to hold the
> formatted data like a stringstream does and the problems with the
> sprintf family. I know a lot of people shun stringstreams because they
> are unacceptably slow in some cases.


I expect that using a temporary stringstream is more efficient than
appending into a string.

>
> For example, we could do something like this:
> int cat_len = 120;
> int mouse_len = 29;
>
> std::string myformattedstring << "The cat is " << a << "cm tall and
> the mouse is " << b << "cm tall.";
>
> As you can see, this would format directly to the string. This would
> be both type safe and length safe and the programmer wouldn't have to
> allocate a temporary variable for a stream. However, I'm not sure how
> efficient it would be. I'm intrigued to know if this can be done and
> and if not, the reasons why.


As you wrote it, it is impossible: you cannot mix variable definition
and initialization this way.

Something possible is:
std::string myformattedstring = string_formater()<<"The cat is "
<<...;

Some very fast formating constructs based on template can be designed
this way ( especially if the maximum size of each element can be
computed beforehand). But they have some limitations.

If you want to see an example, you can lookup the FastFormat library
from Matthew Wilson and its shims technique.


Concerning the form, I'd prefer:
std::string myformattedstring = ("The cat is ",fmt::_1,"cm tall and
the mouse is ",fmt::_2,"cm tall.")
, cat_len, mouse_len;

--
Michael
 
Reply With Quote
 
Victor Bazarov
Guest
Posts: n/a
 
      03-24-2011
On 3/24/2011 11:04 AM, Ricky65 wrote:
> On Mar 24, 2:52 pm, Victor Bazarov<v.baza...@comcast.invalid> wrote:
>> On 3/24/2011 10:38 AM, Ricky65 wrote:
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>> I was thinking about string formatting after reading this article by
>>> Herb Sutter here:
>>> http://www.gotw.ca/publications/mill19.htm

>>
>>> I thought to myself "Why haven't they overloaded the<< operator for
>>> the basic_string class?" like with the iostream. I don't think I'm the
>>> first to have thought of this. I assume performance problems are the
>>> reason this is not done.

>>
>>> This would eliminate the need to make a temporary variable to hold the
>>> formatted data like a stringstream does and the problems with the
>>> sprintf family. I know a lot of people shun stringstreams because they
>>> are unacceptably slow in some cases.

>>
>>> For example, we could do something like this:
>>> int cat_len = 120;
>>> int mouse_len = 29;

>>
>>> std::string myformattedstring<< "The cat is "<< a<< "cm tall and
>>> the mouse is "<< b<< "cm tall.";

>>
>> This syntax is invalid. You either declare an object (and initialize
>> it) or manipulate it using operator<<. You can't do both in the same
>> statement.
>>
>>> As you can see, this would format directly to the string. This would
>>> be both type safe and length safe and the programmer wouldn't have to
>>> allocate a temporary variable for a stream. However, I'm not sure how
>>> efficient it would be. I'm intrigued to know if this can be done and
>>> and if not, the reasons why.

>>
>> It cannot, see above.
>>
>> V
>> --
>> I do not respond to top-posted replies, please don't ask

>
> Sorry, I meant
>
> std::string myformattedstring;
>
> myformattedstring<< "The cat is "<< a<< "cm tall and
> the mouse is "<< b<< "cm tall.";


That is *usually* done with stringstreams:

std:stringstream myformattedstream;
myformattedstream << "The cat it in the hat";

std::string myformattedstring = myformattedstream.str();

There is no need to pollute std::string with the functionality that
already exists in another class.

V
--
I do not respond to top-posted replies, please don't ask
 
Reply With Quote
 
Michael Doubez
Guest
Posts: n/a
 
      03-24-2011
On 24 mar, 16:49, Leigh Johnston <le...@i42.co.uk> wrote:
> On 24/03/2011 15:34, Michael Doubez wrote:
>
>
>
>
>
>
>
>
>
> > On 24 mar, 15:38, Ricky65<ricky...@hotmail.com> *wrote:
> >> I was thinking about string formatting after reading this article by
> >> Herb Sutter here:http://www.gotw.ca/publications/mill19.htm

>
> >> I thought to myself "Why haven't they overloaded the<< *operator for
> >> the basic_string class?" like with the iostream.

>
> > Who is "they" ? The standard committee ?

>
> >> I don't think I'm the
> >> first to have thought of this. I assume performance problems are the
> >> reason this is not done.

>
> > Doing so would shun formating facilities.

>
> > The language definition is geared toward general case. If you have
> > specific needs, you are expected to roll your own. This avoid
> > cluttering the standard with use cases that you can recode or that
> > libraries can provide.

>
> >> This would eliminate the need to make a temporary variable to hold the
> >> formatted data like a stringstream does and the problems with the
> >> sprintf family. I know a lot of people shun stringstreams because they
> >> are unacceptably slow in some cases.

>
> > I expect that using a temporary stringstream is more efficient than
> > appending into a string.

>
> >> For example, we could do something like this:
> >> int cat_len = 120;
> >> int mouse_len = 29;

>
> >> std::string myformattedstring<< *"The cat is "<< *a<< *"cm tall and
> >> the mouse is "<< *b<< *"cm tall.";

>
> >> As you can see, this would format directly to the string. This would
> >> be both type safe and length safe and the programmer wouldn't have to
> >> allocate a temporary variable for a stream. However, I'm not sure how
> >> efficient it would be. I'm intrigued to know if this can be done and
> >> and if not, the reasons why.

>
> > As you wrote it, it is impossible: you cannot mix variable definition
> > and initialization this way.

>
> > Something possible is:
> > std::string myformattedstring = string_formater()<<"The cat is"
> > <<...;

>
> > Some very fast formating constructs based on template can be designed
> > this way ( especially if the maximum size of each element can be
> > computed beforehand). But they have some limitations.

>
> > If you want to see an example, you can lookup the FastFormat library
> > from Matthew Wilson and its shims technique.

>
> > Concerning the form, I'd prefer:
> > std::string myformattedstring = ("The cat is ",fmt::_1,"cm tall and
> > the mouse is ",fmt::_2,"cm tall.")
> > * * * * * * * * * * * * * * * * * ** * * *, cat_len, mouse_len;

>
> That does not lend itself to well to localization; consider boost.format
> instead.


It depends on what you want to achieve. Boost.Format is great for
having complex format (event tabulation IIRC) while others won't need
the internationalisation/localisation but prefer high speed (like in
logging or feeding another program).

See:
http://accu.org/index.php/journals/1539

--
Michael
 
Reply With Quote
 
James Kanze
Guest
Posts: n/a
 
      03-26-2011
On Mar 24, 3:49 pm, Leigh Johnston <le...@i42.co.uk> wrote:
> On 24/03/2011 15:34, Michael Doubez wrote:


[...]
> > Concerning the form, I'd prefer:
> > std::string myformattedstring = ("The cat is ",fmt::_1,"cm tall and
> > the mouse is ",fmt::_2,"cm tall.")
> > , cat_len, mouse_len;


I'd be interested in seeing how that could be implemented
without varargs, and the resulting loss of type safety.

> That does not lend itself to well to localization; consider boost.format
> instead.


boost::format solves one small aspect of localization, but in
practice, it's rarely enough. I had a class which did the same
thing, long before there was boost, and I gradually stopped
maintaining it, because it didn't solve any real problems
satisfactorily. (And unlike boost::format, it didn't really
work with manipulators. And you really want user defined
manipulators to define semantic markup.) As soon as more than
one language is involved, you almost always have to have a
separate dll, with specially written code, for each language.

--
James Kanze
 
Reply With Quote
 
Ricky65
Guest
Posts: n/a
 
      03-28-2011
On Mar 25, 7:06*am, Paavo Helde <myfirstn...@osa.pri.ee> wrote:
> Ricky65 <ricky...@hotmail.com> wrote in news:4f8cb849-5b91-4f44-939c-
> 9865bf3e0...@f30g2000yqa.googlegroups.com:
>
> > Sorry, I meant

>
> > std::string myformattedstring;

>
> > myformattedstring << "The cat is " << a << "cm tall and
> > the mouse is " << b << "cm tall.";

>
> No problem if you really want this, just add a little helper function.
> Note that this essentially duplicates stringstream functionality for
> another class (std::string) actually meant for other purposes.
>
> #include <iostream>
> #include <string>
> #include <sstream>
>
> template<typename T>
> std::string& operator<<(std::string& s, const T& x) {
> * *std:stringstream os;
> * *os << x;
> * *s += os.str();
> * *return s;
>
> }
>
> int main() {
> * *std::string myformattedstring;
> * *int a = 10;
> * *double b = 3.5;
> * *myformattedstring << "The cat is " << a <<
> * * * *"cm tall and the mouse is " << b << "cm tall.";
> * *std::cout << myformattedstring << "\n";
>
>
>
>
>
>
>
> }


Thanks for this example. This was what I had in mind in my original
post. However, am I right in saying that this wouldn't be any faster
than using normal stringstream? If so, I may as well stick to good old
stringstreams.

 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Grouping/Sorting Data in Smart Markers, Better Conditional Formatting sherazam Java 0 10-21-2011 10:21 AM
API for Table Formatting, Better Chinese & Japanese Languages Support sherazam Java 0 10-07-2011 12:34 PM
Re: Parsing Binary Structures; Is there a better way / What is your way? Paul Rubin Python 5 08-06-2009 08:06 AM
Build a Better Blair (like Build a Better Bush, only better) Kenny Computer Support 0 05-06-2005 04:50 AM
Need formatting options menu for formatting hard drive Mark T. Computer Support 3 11-24-2003 11:50 PM



Advertisments
 



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 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57