Is it posible to use the TTF_Render_TextSolid controlled with one integer? I try to use stringstreams like this:
stringstream _minutes;
stringstream _seconds;
stringstream _miliseconds;
_minutes << minutes << ":";
_seconds << seconds << ":";
_miliseconds << miliseconds;
(the variable minutes, seconds and miliseconds was already scoped)
But when I compile this, compile well but then, I run and this says : core dumped. So the error is in the memory part. mmh what happens?
Doing something along the lines of:
stringstream ss;
ss << minutes << ":" << seconds << ":" << miliseconds;
const string str = ss.str();
SDL_Surface* surf = TTF_RenderText_Solid(textFont, str.c_str(), textColor);
Should work without a problem.
Do not store the const char* that comes out of it though! As soon as your str goes out of scope, your const char* won't be valid anymore.
Related
I got the following std::string that I partially create through converting an int to a string:
std::string text = std::string("FPS: " + std::to_string(1000 / d));
Example output:
FPS: 60
Now, I would like to add leading zeros specifically to the int part, such that I get this output:
FPS: 060
I already know how to achieve this for stdout with std::cout << std::setfill('0') << std::setw(5) .
But I haven't found a solution for the simple std::to_string() conversion.
Use a stringstream.
It behaves exactly like std::cout but has a method str() to get the string you created.
For your problem it would probably look like this:
std::stringstream ss;
ss << "FPS: " << std::setfill('0') << std::setw(5) << std::to_string(1000 / d);
std::string text(ss.str());
Edit: To test the performance of this I created a dumb test program:
#include <sstream>
#include <iomanip>
int main()
{
std::stringstream ss;
for(int i=0; i<100000; i++)
{
ss.clear();
ss << "FPS: " << std::setfill('0') << std::setw(5) << std::to_string(i);
std::string text(ss.str());
}
return 0;
}
and compiled it with g++ -O3 main.cpp. I then opened a terminal and started the program through time:
$ time ./a.out
./a.out 1,53s user 0,01s system 99% cpu 1,536 total
So 1.53s for 100k iterations (15.3µs per iteration on average) on my Intel(R) Core(TM) i5-8500 CPU # 3.00GHz CPU running a Linux 5.13.5 kernel the latest libstdc++
It's very long from an instruction perspective, tens of thousands of instructions is costly on small micro-processor, but on a modern system it's hardly ever a problem.
In C++20, you might use std::format
std::format("{:03}", 1000 / d);
You could count the length of the converted string and use that to create a string with zeroes:
size_t min_len = 3;
std::string text = std::to_string(1000 / d);
if(text.size() < min_len) text = std::string(min_len - text.size(), '0') + text;
text = "FPS: " + text;
A performance test comparing using this "strings only" approach to that of using std::stringstream may be interesting if you do this formatting a lot:
quick-bench.com
I am a newbie, writing a c++ code to open and read from multiple files and then dump part of the data into other files.
I want to generate file names in a for loop.
But I can't concatenate string(numbering of file) and string literal(a file extension). The same line of code works at the very beginning of the program, but not at the later part.
int main(int argc, char *argv[])
{
std::cout << std::string("9") + ".dat" << std::endl;
// many more lines
dump = 1;
if (dump == 1){
for (int ilevel=std::max(levelmin,lmin); ilevel < lmax + 1; ilevel++){
std::cout << std::string("9") + ".dat" << std::endl; // crashes here!
std::ofstream fout (std::string("9") + ".dat", std::ios::out | std::ios::binary);
std::cout << grid[ilevel].cube[0] << std::endl;
fout.write ((char*)&grid[ilevel].cube[0], grid[ilevel].cube.size() * sizeof(grid[ilevel].cube[0]));
fout.close();
}
}
...
}
If I put std::cout << std::string("9") + ".dat" << std::endl; at the beginning, it works and prints "9.dat".
but in the later loop, segmentation fault.
In between I call a function that uses stringstream to pad leading zeros to an integer. The function looks:
std::string int2str(const int n, const int m){
std::stringstream ss;
ss << std::setfill('0') << std::setw(m) << n;
std::string s2(ss.str());
ss.clear();
return s2;
}
I don't have a clear understanding about string and stringstream in c++.
But out of many things in my program, this function is the only thing I can think of being relevant. Other parts of codes does not deal with strings. It's mostly array manipulation code.
I've also tried std::string("9") + std::string(".dat")
but had no luck.
What is wrong?
Is there a specific reason why you're using std::string("9") rather than just "9"?
Where does the 9 come from? If its generated as part of a loop or a returned value from a function you can either place the variable itself to be concatenated, or the function that returns it, so:
std::cout << iFileNumber + ".dat" << std::endl;
or
std::cout << fileNumberGenerator() + ".dat" << std::endl;
For the hardcoded examples you've provided, I personally can't see the need for anything other than
std::cout << 9 + ".dat" << endl;
but that could easily just be lack of experience on my part.
For the sake of printing to the command line, its also worth nothing that this is equally acceptable syntax (assuming you're not already aware):
std::cout << 9 << ".dat" << endl;
This question already has answers here:
Can a local variable's memory be accessed outside its scope?
(20 answers)
Closed 7 years ago.
I've been trying to append an integer to a string, and I've tried several solutions here, including:
std::stringstream ss;
ss << gvHours << "\'" << gvMinutes << "\"" << gvSeconds << ":" << gvTicks;
std::string output(ss.str());
return output.c_str();
and
std::stringstream ss;
std::string output = "";
ss << gvHours << "\'" << gvMinutes << "\"" << gvSeconds << ":" << gvTicks;
output = ss.str();
return output.c_str();
The first one gives me an empty string, and the second gives me an unreadable character that Notepad++ displays as "SOH" in a black box. Does anyone have any idea what I'm doing wrong?
Yes, this part
return output.c_str();
is broken.
When you take c_str() from a std::string, you are just getting a c-style pointer to the contents of that string. But you are not getting ownership of the data underlying that string. As soon as you return from the function, that stringstream and string are destroyed (as they are local variables) and the c_str() is a dangling pointer. So the whole thing is undefined behavior.
I fixed it. Here's the code I got that works:
std::stringstream ss;
std::string output;
ss << gvHours << "\'" << gvMinutes << "\"" << gvSeconds << ":" << gvTicks;
output = ss.str();
return output;
And in the function where it was needed:
fprintf(gvLog, ">: %s\n", timeString().c_str());
I'm new to windows programming, and what experience I have to-date has been with C#.
I've been asked to work on a project written by a colleague in C++. He's avoided using any of the .Net functionality as he doesn't like it. I'm trying to add in some debugging output, here is my code:
std::ostringstream strs;
strs << "Average value: " << dbl_sum / (double)_buffer.size() << " Buffer Size: " << _buffer.size();
std::string str = strs.str();
OutputDebugString((LPCTSTR)str.c_str());
However, when I run the program I'm seeing lines like this in the Debug window:
?????????????????????????????›?
My best guess is that it's something to do with my conversion to LPCTSTR, but I got that method from an answer to an old question on here.
Thanks to #Hans Passant I managed to fix this problem. I changed my code to:
std::ostringstream strs;
strs << "Average value: " << dbl_sum / (double)_buffer.size() << " Buffer Size: " << _buffer.size() << std::endl;
std::string str = strs.str();
OutputDebugStringA((LPCSTR)str.c_str());
I Guess your project's char set is UNICODE
when you take ASCII string and convert it to UNICODE you got Gibberish.
To resolve this you need to use wide string types instead of string or to change your program charset to Multi-bytes
You'll need to change these types:
string to wstring,
ostringstream to wostringstream,
"abc" to L"abc"
std::wostringstream strs;
strs << L"Average value: " << dbl_sum / (double)_buffer.size() << L" Buffer Size: " << _buffer.size();
std::wstring str = strs.str();
OutputDebugString(str.c_str());
Hi below is my function:
string Employee::get_print(void) {
string out_string;
stringstream ss;
ss << e_id << " " << type << endl;
out_string = ss.str();
return out_string;
}
e_id and type are int and they contain values from the class Employee. But when I pass them into the stringstream they just clear the string when I try to out put it. But if I don't have a int in the ss << "Some text" << endl; this output fine. What am I doing wrong =S
//Edit
Ok;
This is the calling code:
tmp = cur->get_print();
Where tmp is a string and cur is an Employee Object.
This code...
stringstream out;
out << "Test " << e_id << " " << e_type;
return out.str();
Retruns "Test " and nothing else. If I take out "Test " << my returned string is ""
I'm using GCC 4.2 on Mac OS/X 10.6.2 if that makes any difference.
I too am unable to reproduce this error. As has been mentioned, don't include the endl, as this actually appends a \n and is supposed to flush the write buffer. For this use, it is completely unnecessary and may actually lead to undesirable results...However, the code in your edit/update works just fine for me.
int main(int argc, char* argv[])
{
int e_id = 5;
int e_type = 123456;
stringstream out;
out << "Test " << e_id << " " << e_type;
cout << out.str();
return 0;
}
Produces:
Test 5 123456
My suggestions would be to double check that e_id and e_type are really just native int.
For further testing, you may want to force a cast on the values to see if it helps as such:
out << "Test " << (int)e_id << " " << (int)e_type;
Since I'm unable to reproduce this error, I'm afraid I'm unable to help any further. But best of luck to you!
Ok I have no idea what is going on with stringstream I've tried using it in other parts of my code and it doesn't work with integers. Therefore, I have reverted to using the sprintf C function:
string Employee::get_print(void) {
char out[50];
sprintf(out, "%d %d", e_id, e_type);
string output = out;
return output;
}
This returns the string which is needed.
I have moved into Netbeans and I don't have this problem. So it is an issue with Xcode.
I think the endl is not needed. You only need to write endl if you want to write a newline on a file on on std::cout.
Since you write endl, your stringstream will contain a string with 2 lines of which the second is empty. This probably confuses you. Remove the endl to get only one line.
I've got exactly the same problem - GCC and stringstream returning nothing.
As I found out, the trick is that you have to put some text data before anything else into the stringstream.
This code...
stringstream ss(stringstream::out);
ss << 3.14159;
cout << "'" << ss.str() << "'" << endl;
gets you this result:
''
But if we put a single "" inside the stringstream first...
stringstream ss(stringstream::out);
ss << "" << 3.14159;
cout << "'" << ss.str() << "'" << endl;
the result is as expected:
'3.14159'