7

This is a very simple question and I feel stupid for asking it, but I am pressed for time and I need to figure it out :)

I just need to know how to make a string that contains text and other variables. For instance in Java I can just do this:

String someString;

for(int i = 0; i>10; i++){

someString = ("this text has printed " + i + " times"); //how do I create this line in C++?

System.out.println(someString);

i++;

}

EDIT 4:

Ok, Rahul G's answer below works pretty good, and the program compiles and ok, but when I run it instead of getting the string I want for the file name, I get a bunch of numbers. For instance: << "frame " << i << " .jpg" creates: "013679000.jpg" instead of "frame 0.jpg" like I want. Any thoughts?

for(int i = 0; frames; i++)
{  
  frame = cvQueryFrame(capture); 
  std::string s = static_cast<std::ostringstream &>(std::ostringstream() << argv[1] <<  i << " .jpg").str(); 
  cvSaveImage(s.c_str(), frame);
} 
Hasturkun
  • 35,395
  • 6
  • 71
  • 104
ubiquibacon
  • 10,451
  • 28
  • 109
  • 179
  • 1
    Do you really want to make the string, or just print it? In the latter case you could use @reko_t's solution, but do `std::cout << "this text has printed " << i << " times";` – Andrew Jaffe Mar 24 '10 at 08:21
  • 1
    `cvSaveImage(oss.str(), frame);` doesn't work? – Naveen Mar 24 '10 at 08:27
  • no it does not work, f****** OpenCV! The wiki says the first argument needs to be a string file name, but VS keeps giving me this error: Error 23 error C2664: 'cvSaveImage' : cannot convert parameter 1 from 'std::basic_string<_Elem,_Traits,_Ax>' to 'const char *' – ubiquibacon Mar 24 '10 at 08:38
  • 3
    @typoknig: Try `cvSaveImage(oss.str().c_str(), frame);`. See my answer for explanation. – missingfaktor Mar 24 '10 at 08:43
  • I suggested edit for your original code. You took half of code from my answer and mixed it incorrectly with half from your post. `str()` is member of `std::ostringstream` and `c_str()` is a member of `std::string`. Since `s` is an `std::string`, you just need to call `c_str()` on it. That is, `cvSaveImage(s.c_str(), frame);` – missingfaktor Mar 24 '10 at 08:58
  • I did that already and it still doesn't work I tried multiple variations of what you posted and then re-posted the version that had the least amount of errors (when I used all of what you provided I had 4 errors when I mixed it with what I had I had 3). – ubiquibacon Mar 24 '10 at 09:00
  • @typoknig Rahul's code is incorrect. –  Mar 24 '10 at 09:00
  • No one appears to have suggested `include ` yet. – Daniel Earwicker Mar 24 '10 at 09:01
  • @typoknig: Neil is right. See the new edited answer. – missingfaktor Mar 24 '10 at 09:06
  • The operator << of std::ostringstream is inherited from std::basic_ostream, hence it returns a reference to std::basic_ostream&. To use .str() on it, you need to cast it first. However it'd be so much cleaner to just assign it to a separate variable first, and use .str() on it. – reko_t Mar 24 '10 at 09:11
  • 1
    This question has some related information on the casting you need: http://stackoverflow.com/questions/2433071/turning-temporary-stringstream-to-c-str-in-single-statement – AshleysBrain Mar 24 '10 at 09:14

8 Answers8

12

You can use stringstreams for this:

for (int i = 0; i < 10; i++) {
    std::ostringstream ss;
    ss << "this text has printed " << i << " times";
    std::cout << ss.str() << std::endl;
}
reko_t
  • 55,302
  • 10
  • 87
  • 77
7

Java:

int i = 5;
double d = 2.23606798;
String s = "Square root of "+i+" is "+d;

C++:

int i = 5;
double d = 2.23606798;
std::ostringstream oss;
oss << "Square root of " << i << " is " << d;
std::string s = oss.str();
// If you need C style string...
char const *s0 = s.c_str();

Please note that the std::ostringstream class resides in <sstream> header.

Edit:

Your code (corrected):

for(int i = 0; frames; i++) { 
  frame = cvQueryFrame(capture);
  std::ostringstream oss;
  oss << "frame " << i << " .jpg";
  cvSaveImage(oss.str().c_str(), frame);
}
missingfaktor
  • 90,905
  • 62
  • 285
  • 365
  • This won't work, as the result of your bracketed expression containing the stringstream is an ostream, which has no str() member. –  Mar 24 '10 at 09:00
  • @Neil: Thanks for pointing that out. Added an appropriate cast to make that work. – missingfaktor Mar 24 '10 at 09:07
  • @Rahul I don't see why you feel the need to create the stringstream as a nameless temporary. Giving it a name is actually clearer, shorter, and given the OP's C++ skills, easier for a newbie to understand. –  Mar 24 '10 at 09:11
  • SUCCESS! Thank you all very much! I think all of you know what is going on, OpenCV just sucks, I suggest avoiding it unless you have no other choice :) – ubiquibacon Mar 24 '10 at 09:11
  • @Neil: I wanted to make it look more like the Java version. Anyways, I edited the code again to make it easy to understand for newbies. Thanks for the suggestions. – missingfaktor Mar 24 '10 at 09:20
  • Ok, the program compiles and ok, but when I run it instead of getting the string I want for the file name, I get a bunch of numbers. For instance: << "frame " << i << " .jpg" creates: "013679000.jpg" instead of "frame 0.jpg" like I want. Any thoughts? – ubiquibacon Mar 24 '10 at 09:26
  • @typoknig: Try the new code. The reason why that didn't work is described here: http://stackoverflow.com/questions/2433071/turning-temporary-stringstream-to-c-str-in-single-statement/2433143#2433143 – missingfaktor Mar 24 '10 at 09:29
  • It doesn't like the new code. I get the following 3 errors: error C2065: 's' : undeclared identifier error C2228: left of '.str' must have class/struct/union error C2228: left of '.c_str' must have class/struct/union It likes your other code though. – ubiquibacon Mar 24 '10 at 09:37
  • My bad. It should be `oss`, not `s`. **Again** edited my post... – missingfaktor Mar 24 '10 at 09:39
  • @Rahul I really suggest you compile your code before posting! –  Mar 24 '10 at 09:39
  • @Neil: will do that from next time :-) – missingfaktor Mar 24 '10 at 09:40
  • Haha, you are doing much better than I would do, plus it is late! You were right though, that got it fixed. Tomorrow when I am a little more lucid I will look over those other threads and see why this works like it does. Writting in c++ is tough when a barely know .net or java :) – ubiquibacon Mar 24 '10 at 09:53
3

There is one more way to do this: use boost::lexical_cast (I know, that it based on std::stringstream, but it pretty useful):

#include <string>
#include <iostream>
#include <boost\lexical_cast.hpp>

int _tmain(int argc, _TCHAR* argv[])
{
    int i = 0;
    std::string result = "this text has printed " + boost::lexical_cast<std::string, int>(i) + " times";
    std::cout<<result<<std::endl;
    std::cin.get();
    return 0;
}
Sergey Teplyakov
  • 11,477
  • 34
  • 49
  • This approach should be encouraged. Boost::lexical_cast<> is concise, self-documenting and in keeping with other C++ cast or conversion operations. I believe lexical_cast has been proposed for C++ TR2, so it may become standard (although not soon). – Rhubbarb Mar 24 '10 at 10:48
1

I posted some code to create strings in place here (basically a wrapper to hide the std::ostringstream and make calling code cleaner). The usage would be:

void f( std::string const & ); // or std::string, but not std::string&

int var = 5;
f( make_string() << "prefix " << var << " postfix" );

Since you need a const char * you should use:

void g( const char * );
std::string s = make_string() << "prefix " << var << " postfix";
g( s.str() );
Community
  • 1
  • 1
David Rodríguez - dribeas
  • 204,818
  • 23
  • 294
  • 489
0

You know you have a bug in your code?? You're incrementing i in the for() statement and at the end of the loop!! But I digress.

Use printf:

printf("This text has printed %d times\n",i)

Hope that helps!

Michael Howard-MSFT
  • 3,232
  • 2
  • 16
  • 11
0

If the error you're getting is "error C2664: 'cvSaveImage' : cannot convert parameter 1 from 'std::basic_string<_Elem,_Traits,_Ax>' to 'const char *" then you need a C style string not a C++ one:

cvSaveImage(oss.str().c_str(), frame);
Ian G
  • 10,709
  • 6
  • 30
  • 34
0

How about cvSaveImage(oss.str().c_str(), frame); ? That will make an old C-type zero terminated string which hopefully OpenCV will accept.

Terje Mikal
  • 938
  • 6
  • 16
0

This is a version of your latest code with your specific function cals removed so I can compile it. It compiles and works:

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

using namespace std;

int main() {

    for(int i = 0; i < 10; i++) { 
        ostringstream os;
        os << "frame" << i << " .jpg";
        string s = os.str();
        cout << s << "\n"; 
     }
}