Why is my string not being printed?
Asked Answered
R

5

7

I have some code that, in its smallest complete form that exhibits the problem (being a good citizen when it comes to asking questions), basically boils down to the following:

#include <string>
#include <iostream>
int main (void) {
    int x = 11;
    std::string s = "Value was: " + x;
    std::cout << "[" << s << "]" << std::endl;
    return 0;
}

and I'm expecting it to output

[Value was: 11]

Instead, instead of that, I'm getting just:

[]

Why is that? Why can I not output my string? Is the string blank? Is cout somehow broken? Have I gone mad?

Reisman answered 3/2, 2011 at 6:9 Comment(3)
You need to include <string> for this to "work" in a compliant manner, by the way.Templas
Good point, how is this even compiling?Internode
gcc (Ubuntu 4.4.3-4ubuntu5) 4.4.3 compiles that without errors - maybe it's just forgiving. In any case, adding string doesn't help so I'll add it to the question so we're more kosher. However, Xeo beat me to it so thanks :-)Reisman
R
8

"Value was: " is of type const char[12]. When you add an integer to it, you are effectively referencing an element of that array. To see the effect, change x to 3.

You will have to construct an std::string explicitly. Then again, you cannot concatenate an std::string and an integer. To get around this you can write into an std::ostringstream:

#include <sstream>

std::ostringstream oss;
oss << "Value was: " << x;
std::string result = oss.str();
Rood answered 3/2, 2011 at 6:15 Comment(9)
In this case, since the number is 11 and the length of the string is 11, the resulting pointer points right at the null terminator.Neibart
It's of the type const char[12], actually.Templas
char[11] actually (I think).Reisman
@paxdiablo: const char[12]. It's zero-terminated implicitly.Rood
Sorry 'bout that, you're actually right about the 12, I miscounted. However, you're not quite so right about the const. While it's undefined to try and change them, string literals are char, not const char. Except the wide ones which aren't char, but I'm still pretty sure those aren't const either, even though I've never used them. Not that it affects my upvote for this answer :-)Reisman
or alternatively the statement can be modified as std::string s = string("Value was: ") + x;Global
It used to be char[], but according to glenmccl.com/ansi_014.htm it was decided to change it to const char[]. I don't know if this change already applies or if it's for the upcoming C++ standard.Rood
@hype: No, it cannot. This gives a no match for ‘operator+’ in std::basic_string error.Rood
@pax: §2.13.4/1, C++03: "An ordinary string literal has type “array of n const char” and static storage duration (3.7), where n is the size of the string"Templas
S
4

You can't add a character pointer and an integer like that (you can, but it won't do what you expect).

You'll need to convert the x to a string first. You can either do it out-of-band the C way by using the itoa function to convert the integer to a string:

char buf[5];
itoa(x, buf, 10);

s += buf;

Or the STD way with an sstream:

#include <sstream>

std::ostringstream oss;
oss << s << x;
std::cout << oss.str();

Or directly in the cout line:

std::cout << text << x;
Sismondi answered 3/2, 2011 at 6:13 Comment(3)
Wouldn't he still run into problems because x is of type int, not string or char*?Transcendence
That gives me [Value was <CTRL-K>] (had to pipe through od -xcb to see what was going on there.Reisman
When you do S += x; it is converting integer 11 to char 11 and tries to get the corresponding ASCII character.Elenaelenchus
C
4

Amusing :) That's what we pay for C-compatibility and the lack of a built-in string.

Anyway, I think the most readable way to do it would be:

std::string s = "Value was: " + boost::lexical_cast<std::string>(x);

Because the lexical_cast return type is std::string here, the right overload of + will be selected.

Churchless answered 3/2, 2011 at 7:49 Comment(0)
T
2

C++ doesn't concatenate strings using the the + operator. There's also no auto-promote from data types to string.

Transcendence answered 3/2, 2011 at 6:13 Comment(0)
P
2

In C/C++, you cannot append an integer to a character array using the + operator because a char array decays to a pointer. To append an int to a string, use ostringstream:

#include <iostream>
#include <sstream>

int main (void) {  
  int x = 11;
  std::ostringstream out;
  out << "Value was: " << x;
  std::string s = out.str();
  std::cout << "[" << s << "]" << std::endl;
  return 0;
}
Plauen answered 3/2, 2011 at 6:16 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.