String with integers?

M

mlt

In java an int can be included in a string like:

String str = ""+33 + "strings";

In c++ I have only found:

std::string str = "test";
std::stringstream out;
out << 222;
str = str + out.str();

Is that really the only way to do this in C++?
 
M

mlt

Ok so its not possible to convert an integer to a string without writing a
small function?
 
A

Alf P. Steinbach

* mlt:
In java an int can be included in a string like:

String str = ""+33 + "strings";

In c++ I have only found:

std::string str = "test";
std::stringstream out;
out << 222;
str = str + out.str();

Is that really the only way to do this in C++?

No, there are umpteen ways, but the core language and standard library does not
support the simple Java syntax.

In C++ you decide what libraries to use, or you create the functionality.

E.g., check out boost::lexical_cast, from the Boost library.

Or if installing Boost sounds daunting (note: you don't have to build anything
to use simple functionality like lexical_cast), you can create such
functionality yourself by -- yes -- writing appropriate small routines
and/or classes.

And that is probably best, because for reasons of efficiency you really
shouldn't use string value concatenation as the default. For almost no matter
the language it leads easily to O(n^2) behavior in loops, that is, time that
increases as the square of the number of items, which goes slow very fast. :)
Instead preferentially concatenate on to the end of a string variable, like


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


//--------------------------------- Machinery:

std::string stringFrom( int x )
{
std::eek:stringstream stream;
stream << x;
return stream.str();
}

class S
{
private:
std::string myString;
public:
operator std::string& () { return myString; }
operator std::string const& () const { return myString; }
};

std::string& operator<<( std::string& s, char const rhs[] )
{
return s.append( rhs );
}

std::string& operator<<( std::string& s, int rhs )
{
return s.append( stringFrom( rhs ) );
}


//--------------------------------- Example usage:

void foo( std::string const& s )
{
std::cout << s << std::endl;
}

int main()
{
// Java: foo( "Level " + 42 + "." )
foo( S() << "Level " << 42 << "." );
}
</code>


For reuse, add "inline" to each routine definition and place the machinery in a
header file, which you can then just #include.

Hrmf, this should really be a FAQ.


Cheers & hth.,

- Alf
 
P

peter koch

In java an int can be included in a string like:

String str = ""+33 + "strings";

In c++ I have only found:

  std::string str    = "test";
  std::stringstream out;
  out << 222;
  str = str +  out.str();

Is that really the only way to do this in C++?

Yes. And that is IMHO the correct way to do it. The stringstream is
the flexible approach and also the typesafe way to do stuff. Do you
really want to have string + <anything> work regardless of the type of
<anything>? On reflection, I believe not.

/Peter
 
V

Vladyslav Lazarenko

Guys,

It looks like we forgot about Boost.Format. Example:

int i = 1986;
const char s[] = "STR";

std::string res = boost::str(boost::format("This is my number: %1%.
This is my string: %2%") % i % s);
 
J

Jorgen Grahn

In java an int can be included in a string like:

String str = ""+33 + "strings";

In c++ I have only found:

std::string str = "test";
std::stringstream out;
out << 222;
str = str + out.str();

Is that really the only way to do this in C++?

It looks better when you rewrite it without operator+ :

std::stringstream out;
out << "test" << 222;
// use out.str();

You might also find that what you really want to do with the string is
to place it on a stream, so you can skip the intermediate string.

/Jorgen
 
J

James Kanze

In java an int can be included in a string like:
String str = ""+33 + "strings";

Which is a nice source of errors, and a serious design flaw.
In c++ I have only found:
std::string str = "test";
std::stringstream out;
out << 222;
str = str + out.str();
Is that really the only way to do this in C++?

Yep. Strings are not formatters; formatting is done by
ostream. In Java, of course, if you want to do it right,
and avoid confusion and maintenance problems, you use
java.text.Format. (The basic problem, of course, is that
there are many valid conversions of an int to a string. In
anything but toy programs, you generally have to specify
some of the details.)
 
J

James Kanze

It looks like we forgot about Boost.Format. Example:
int i = 1986;
const char s[] = "STR";
std::string res = boost::str(boost::format("This is my number: %1%.
This is my string: %2%") % i % s);

The problem is that the use of '%' as both the operator and
the format specifier very quickly leads to unreadable
expressions (not to mention the fact that the precedence of
% is wrong). The standard library's choice of << here is
about the best you can do if you insist on an operator; a
better solution would be to use a named function, or even an
operator(), e.g.:

std::string res( Format(
"This is my number: %1%. This is my string: %2%" )
.with( i )
.with( s )
.str() ) ;
 
A

Alf P. Steinbach

* James Kanze:
Which is a nice source of errors, and a serious design flaw.




Yep. Strings are not formatters; formatting is done by
ostream. In Java, of course, if you want to do it right,
and avoid confusion and maintenance problems, you use
java.text.Format. (The basic problem, of course, is that
there are many valid conversions of an int to a string. In
anything but toy programs, you generally have to specify
some of the details.)

No, the difference between general formatting with zillions of options, and
default simple conversion of an integer to string, is just that, zillions of
options versus default simple.

In some cases you (or perhaps not "you" you, but the generic you) want one, in
other cases the other.

Whether the program is toy or the next Photoshop has nothing to do with it; in
both kinds of program the default simple conversion is the one most often
required, and the zillions-of-options one the one least often required.

And formatting isn't necessarily done by ostream.

The nice thing about C++ is that we can choose, and many choose to not use
iostreams except for -- heh, toy programs. ;-)


Cheers,

- Alf
 
J

Jorgen Grahn

* James Kanze: .... ....
Whether the program is toy or the next Photoshop has nothing to do with it; in
both kinds of program the default simple conversion is the one most often
required, and the zillions-of-options one the one least often required.

I find that with integers, I usually have to specify the width, for
alignment in tables. Often hex too, although I guess most other
applications do not print a lot of hex. With float and double, I
think you almost *always* want to specify the precision, so you do not
mislead your users by printing lots of digits which are deep within
the numerical error.
The nice thing about C++ is that we can choose, and many choose to not use
iostreams except for -- heh, toy programs. ;-)

With other peoples' classes, you have no choice. If they can be
printed at all, it's by placing them on an ostream. There is no other
universally accepted way.

/Jorgen
 
A

Alf P. Steinbach

* Jorgen Grahn:
I find that with integers, I usually have to specify the width, for
alignment in tables.

Well, that's also the case for strings. And when you can do that for strings,
then why should that functionality be duplicated for the conversion of integer
to string? That redundant functionality just adds complexity and (when it's
used) makes it harder to do simple things like aligning headers in columns, and
collides directly with the principle of separation of concerns.

And speaking of separation of concerns, if you need a tabular presentation, why
try to shoehorn also that into conversion integer -> string.

Why not, regarding that presentation issue, generate just a CSV file/stream of
data, or XML, whatever pure data format (one concern, data) and run it through a
filter generating e.g. XHTML (second concern, presentation)? It's simpler. And
it's far more flexible. And it allows you to avoid loss of precision. And it's
better for compatibility with other programs and future versions of current one.

Often hex too, although I guess most other
applications do not print a lot of hex. With float and double, I
think you almost *always* want to specify the precision, so you do not
mislead your users by printing lots of digits which are deep within
the numerical error.
Yah.



With other peoples' classes, you have no choice. If they can be
printed at all, it's by placing them on an ostream. There is no other
universally accepted way.

Huh.

The PC I'm writing this on is chock full of classes whose objects can generate
textual representations of themselves in various ways, and so it is on every
Windows PC; there are thousands of classes. Some of them are COM classes, others
are .NET classes. I've yet to see any of them printing to C++ std::eek:stream.

So there. :)

Not that I necessarily recommend either technology mentioned above for any given
purpose.

It's just that, by simple inspection of nearest computer, your "universally
accepted way" seems to actually be very much far less than universally accepted.


Cheers & hth.,

- Alf
 
J

James Kanze

I find that with integers, I usually have to specify the
width, for alignment in tables. Often hex too, although I
guess most other applications do not print a lot of hex. With
float and double, I think you almost *always* want to specify
the precision, so you do not mislead your users by printing
lots of digits which are deep within the numerical error.

Alf's actually at least partially right with regards to
integers. There is a more or less reasonable default, which is
sufficient for debugging and trace outputs, at least. This
doesn't extend to other types, however, and even with integers,
you'll often want something other than the default.

What else is there to choose from? <cstdio> is a design
disaster. The original iostream was actually pretty good, and
could even serve as a model solution for some design problems.
(Note the different techniques used to allow extension, e.g. to
support user defined types, or to support user defined sinks and
sources.) I don't think there's any way the changes made by the
standards committee can be considered an improvement, but at
least, you can ignore them most of the time.
With other peoples' classes, you have no choice. If they can
be printed at all, it's by placing them on an ostream. There
is no other universally accepted way.

Well, boost::format (or my older GB_Format) could handle them.
In both cases, of course, because they're just wrappers around
ostream.
 
J

Jorgen Grahn

* Jorgen Grahn: .... ....
Why not, regarding that presentation issue, generate just a CSV file/stream of
data, or XML, whatever pure data format (one concern, data) and run it through a
filter generating e.g. XHTML (second concern, presentation)? It's simpler. And
it's far more flexible. And it allows you to avoid loss of precision. And it's
better for compatibility with other programs and future versions of current one.

I feel about XML as you feel about iostreams ...

More often than not, my programs generate output in some homegrown but
documented text file format, e.g. lines of name-whitespace-value. Then
it's polite to human readers to align columns so they can eyeball the
data.

But yes, when I sometimes generate HTML or tbl(1) tables, I do not
have to use any padding mechanisms.

....
Huh.

The PC I'm writing this on is chock full of classes whose objects can generate
textual representations of themselves in various ways, and so it is on every
Windows PC; there are thousands of classes. Some of them are COM classes, others
are .NET classes. I've yet to see any of them printing to C++ std::eek:stream.

OK, but I meant "no other universally accepted way /within standard C++/".
(Although I suspect there are heretics^Wsub-cultures who use toString()
methods.)

/Jorgen
 
D

Daniel Pitts

look up itoa then :)
mlt said:
Well I was more looking for int to string and not the other way around.


wp8088 said:
http://www.cplusplus.com/reference/clibrary/cstdlib/atoi.html

#include <cstdlib>
#include <iostream>

using namespace std;

int main(int argc, char *argv[])
{
string str="2";
int i;
i=atoi(str.c_str());
i=i+2;
cout<<i<<endl;
system("PAUSE");
return EXIT_SUCCESS;
}

Victor Bazarov said:
wp8088 wrote:
The easiest way would use the std::atoi

What's that?

V
 
J

James Kanze

look up itoa then :)

Look it up where? It's not part of standard C++. It's not
defined by Posix. It's not present in the man pages on my
machines (Solaris and Linux). It sounds like something very
implementation specific; whatever it is, it's certainly not
portable. (I do seem to remember it being present in some older
Unix---AT&T's version 7, or something like that. But I doubt
many people are running that.)
 
R

rishabh

In java an int can be included in a string like:

String str = ""+33 + "strings";

In c++ I have only found:

  std::string str    = "test";
  std::stringstream out;
  out << 222;
  str = str +  out.str();

Is that really the only way to do this in C++?

The best thing you can do is use following code instead:

std::string str = "test";
char temp[100];
str += itoa(222, temp, 10);
 
D

Daniel Pitts

James said:
Look it up where? It's not part of standard C++. It's not
defined by Posix. It's not present in the man pages on my
machines (Solaris and Linux). It sounds like something very
implementation specific; whatever it is, it's certainly not
portable. (I do seem to remember it being present in some older
Unix---AT&T's version 7, or something like that. But I doubt
many people are running that.)

Indeed, my mistake. Its been so long since I've had to worry about
low-level string manipulation that I didn't realize itoa was a
non-standard extension.

stringstream seems like the way to go then.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
474,161
Messages
2,570,892
Members
47,426
Latest member
MrMet

Latest Threads

Top