How to i add a number to a string? - c++

I want to do something like this (showing what FPS im running at in my SDL game):
SDL_WM_SetCaption("FPS: " + GetTicks(&fps)/1000.f, NULL);
But Visual Studio intellisens complains that expression must have integral or enum type.
What have i done wrong?

If this really is C++, consider streams;
std::ostringstream str;
str << "FPS: " << GetTicks(&fps)/1000.;
SDL_WM_SetCaption(str.str().c_str(), NULL);

C does not support conversion of simple types (like int or float) to more complex types (like strings).
You should check the sprintf function:
char buffer[64];
sprintf("FPS: %f", GetTicks(&fps)/1000.f);
SDL_WM_SetCaption(buffer, NULL);

In C, you can do this using sprintf.
Check out this link:
http://msdn.microsoft.com/en-us/library/ybk95axf(v=vs.71).aspx
Don't use + for adding char pointers (that's what they are in C, not strings).
EDIT:
If this is C++, as per the edit, use std::string, which has the + operator overloaded. You'll still need to convert the number to a string though.
Also, it's called concatenation.

You can either use strings, or if you are already settling for the new current C++ standard, there is also std::to_string:
#include <string>
#include <iostream>
int main() {
const std::string str = "Foobar " + std::to_string(42);
std::cout << str << '\n';
}

Related

How to concat string and float

I have a simple variable:
float t = 30.2f;
How do I add it to a string?
char* g = "Temperature is " + h?
Any guaranteed way (I don't have Boost for instance, and unsure of what version of c++ I have) I can get this to work on a microcontroller?
For simple cases, you can just use the std::string class and the std::to_string function, which have both been part of C++ for a long time.
#include <string>
#include <iostream>
int main()
{
float t = 30.2;
std::string r = "Temperature is " + std::to_string(t);
std::cout << r;
}
However, std::to_string doesn't give you much control over the formatting, so if you need to specify a field width or a number of digits after the decimal point or something like that, it would be better to see lorro's answer.
If you have an incomplete implementation of the C++ standard library on your microcontroller so you can't use the functions above, or maybe you just want to avoid dynamic memory allocation, try this code (which is valid in C or C++):
float t = 30.2;
char buffer[80];
sprintf(buffer, "Temperature is %f.", t);
Note that buffer must be large enough to guarantee there will never be a buffer overflow, and failing to make it large enough could cause crashes and security issues.
std::ostringstream oss;
oss << t;
std::string s = "Temperature is " + oss.str();
Then you can use either the string or the c_str() of it (as const char*).
If, for some reason, you don't have standard library, you can also use snprintf() et. al. (printf-variants), but then you need to do the buffer management yourself.
For the sake of completeness, C++20 introduces std::format for fluent string formatting of this sort:
#include <format>
#include <iostream>
#include <string>
int main() {
float t = 30.2f;
std::string s = std::format("Temperature is {}!\n", t);
std::cout << s;
}
Do note that compiler support for the format library is still underway. GCC does not yet support it, and Clang only has experimental support1 in 14.0+.
1 requires LLVM to be compiled with -DLIBCXX_ENABLE_INCOMPLETE_FEATURES=ON

Creating binary (custom length) string in C++ [duplicate]

If I want to construct a std::string with a line like:
std::string my_string("a\0b");
Where i want to have three characters in the resulting string (a, null, b), I only get one. What is the proper syntax?
Since C++14
we have been able to create literal std::string
#include <iostream>
#include <string>
int main()
{
using namespace std::string_literals;
std::string s = "pl-\0-op"s; // <- Notice the "s" at the end
// This is a std::string literal not
// a C-String literal.
std::cout << s << "\n";
}
Before C++14
The problem is the std::string constructor that takes a const char* assumes the input is a C-string. C-strings are \0 terminated and thus parsing stops when it reaches the \0 character.
To compensate for this, you need to use the constructor that builds the string from a char array (not a C-String). This takes two parameters - a pointer to the array and a length:
std::string x("pq\0rs"); // Two characters because input assumed to be C-String
std::string x("pq\0rs",5); // 5 Characters as the input is now a char array with 5 characters.
Note: C++ std::string is NOT \0-terminated (as suggested in other posts). However, you can extract a pointer to an internal buffer that contains a C-String with the method c_str().
Also check out Doug T's answer below about using a vector<char>.
Also check out RiaD for a C++14 solution.
If you are doing manipulation like you would with a c-style string (array of chars) consider using
std::vector<char>
You have more freedom to treat it like an array in the same manner you would treat a c-string. You can use copy() to copy into a string:
std::vector<char> vec(100)
strncpy(&vec[0], "blah blah blah", 100);
std::string vecAsStr( vec.begin(), vec.end());
and you can use it in many of the same places you can use c-strings
printf("%s" &vec[0])
vec[10] = '\0';
vec[11] = 'b';
Naturally, however, you suffer from the same problems as c-strings. You may forget your null terminal or write past the allocated space.
I have no idea why you'd want to do such a thing, but try this:
std::string my_string("a\0b", 3);
What new capabilities do user-defined literals add to C++? presents an elegant answer: Define
std::string operator "" _s(const char* str, size_t n)
{
return std::string(str, n);
}
then you can create your string this way:
std::string my_string("a\0b"_s);
or even so:
auto my_string = "a\0b"_s;
There's an "old style" way:
#define S(s) s, sizeof s - 1 // trailing NUL does not belong to the string
then you can define
std::string my_string(S("a\0b"));
The following will work...
std::string s;
s.push_back('a');
s.push_back('\0');
s.push_back('b');
You'll have to be careful with this. If you replace 'b' with any numeric character, you will silently create the wrong string using most methods. See: Rules for C++ string literals escape character.
For example, I dropped this innocent looking snippet in the middle of a program
// Create '\0' followed by '0' 40 times ;)
std::string str("\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00", 80);
std::cerr << "Entering loop.\n";
for (char & c : str) {
std::cerr << c;
// 'Q' is way cooler than '\0' or '0'
c = 'Q';
}
std::cerr << "\n";
for (char & c : str) {
std::cerr << c;
}
std::cerr << "\n";
Here is what this program output for me:
Entering loop.
Entering loop.
vector::_M_emplace_ba
QQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQ
That was my first print statement twice, several non-printing characters, followed by a newline, followed by something in internal memory, which I just overwrote (and then printed, showing that it has been overwritten). Worst of all, even compiling this with thorough and verbose gcc warnings gave me no indication of something being wrong, and running the program through valgrind didn't complain about any improper memory access patterns. In other words, it's completely undetectable by modern tools.
You can get this same problem with the much simpler std::string("0", 100);, but the example above is a little trickier, and thus harder to see what's wrong.
Fortunately, C++11 gives us a good solution to the problem using initializer list syntax. This saves you from having to specify the number of characters (which, as I showed above, you can do incorrectly), and avoids combining escaped numbers. std::string str({'a', '\0', 'b'}) is safe for any string content, unlike versions that take an array of char and a size.
In C++14 you now may use literals
using namespace std::literals::string_literals;
std::string s = "a\0b"s;
std::cout << s.size(); // 3
Better to use std::vector<char> if this question isn't just for educational purposes.
anonym's answer is excellent, but there's a non-macro solution in C++98 as well:
template <size_t N>
std::string RawString(const char (&ch)[N])
{
return std::string(ch, N-1); // Again, exclude trailing `null`
}
With this function, RawString(/* literal */) will produce the same string as S(/* literal */):
std::string my_string_t(RawString("a\0b"));
std::string my_string_m(S("a\0b"));
std::cout << "Using template: " << my_string_t << std::endl;
std::cout << "Using macro: " << my_string_m << std::endl;
Additionally, there's an issue with the macro: the expression is not actually a std::string as written, and therefore can't be used e.g. for simple assignment-initialization:
std::string s = S("a\0b"); // ERROR!
...so it might be preferable to use:
#define std::string(s, sizeof s - 1)
Obviously you should only use one or the other solution in your project and call it whatever you think is appropriate.
I know it is a long time this question has been asked. But for anyone who is having a similar problem might be interested in the following code.
CComBSTR(20,"mystring1\0mystring2\0")
Almost all implementations of std::strings are null-terminated, so you probably shouldn't do this. Note that "a\0b" is actually four characters long because of the automatic null terminator (a, null, b, null). If you really want to do this and break std::string's contract, you can do:
std::string s("aab");
s.at(1) = '\0';
but if you do, all your friends will laugh at you, you will never find true happiness.

C++ how to add more strings into a method

I have been working in Java since I started programming and decided to learn c++.
What I wrote in Java looked like this:
showMessage("Hello world" + randomNumber);
And it showed text + integer or float or whatever. But it wont work in c++.
Error message by xCode: Invalid operands to binary expression ('const char *' and 'float')
Cheers!
You can do a sprintf according to Anton, or to be more c++:
std::stringstream ss;
ss << "Hello, world " << randomNumber;
showmessage(ss.str());
(there's nothing wrong with sprintf, especially if you use snprintf instead).
ostringstream os;
os<<"HelloWorld"<<randomnumber;
string s;
s = os.str();
string s now contains the string you want as a string object.
Also you can use boost::lexical_cast to cast numbers into strings which is fastest method in most cases:
showMessage("Hello world" + boost::lexical_cast<std::string>(randomNumber));
showMessage declaration is
void showMessage(cosnt std::string& message)
Consider adding a new function that is able to convert several types to std::string:
template<typename ty>
string to_str(ty t)
{
stringstream ss; ss << t;
return ss.str();
}
Usage:
"Hello World " + to_str(123)
Define a class S. Then write
showMessage( S() << "Hello world" << randomNumber );
I've coded up the S class too many times for SO, and it's a good exercise to create it, hence, not providing the source code.
Note that you can reasonably call it StringWriter or something like that, and then just use a typedef for more concise code in function calls.
I am not sure if c-style answer is fine, but I have already answer it here in a cocos2d-x question.
Trying to set up a CCLabelTTF with an integer as part of it's string in Cocos2d-X C++
With C++11:
showMessage("Hello world" + std::to_string(randomNumber));
you should print into the char* instead.
You could do something like
char* tempBuffer = new char[256];
sprintf_s(tempBuffer, 256, "Hello world %d", randomNumber);
showMessage(tempBuffer);
In C++ the standard way to concatenate strings and primitives is to use stringstream. Which fulfils the same functionality (and a little bit more) as StringBuilder in Java (of course its API differs). However, if you are comfortable using cout then you should be fine.
eg.
#include <iostream>
#include <sstream>
#include <string>
using namespace std;
int main () {
stringstream ss;
ss << "Some string - " << 124; // build string
string str = ss.str(); // extract string
cout << str << endl;
return 0;
}
Quick reference for stringstream http://www.cplusplus.com/reference/iostream/stringstream/stringstream/

In C++, I thought you could do "string times 2" = stringstring?

I'm trying to figure out how to print a string several times. I'm getting errors. I just tried the line:
cout<<"This is a string. "*2;
I expected the output: "This is a string. This is a string.", but I didn't get that. Is there anything wrong with this line? If not, here's the entire program:
#include <iostream>
using namespace std;
int main()
{
cout<<"This is a string. "*2;
cin.get();
return 0;
}
My compiler isn't open because I am doing virus scans, so I can't give the error message. But given the relative simplicity of this code for this website, I'm hoping someone will know if I am doing anything wrong by simply looking.
Thank you for your feedback.
If you switch to std::string, you can define this operation yourself:
std::string operator*(std::string const &s, size_t n)
{
std::string r; // empty string
r.reserve(n * s.size());
for (size_t i=0; i<n; i++)
r += s;
return r;
}
If you try
std::cout << (std::string("foo") * 3) << std::endl
you'll find it prints foofoofoo. (But "foo" * 3 is still not permitted.)
There is an operator+() defined for std::string, so that string + string gives stringstring, but there is no operator*().
You could do:
#include <iostream>
#include <string>
using namespace std;
int main()
{
std::string str = "This is a string. ";
cout << str+str;
cin.get();
return 0;
}
As the other answers pointed there's no multiplication operation defined for strings in C++ regardless of their 'flavor' (char arrays or std::string). So you're left with implementing it yourself.
One of the simplest solutions available is to use the std::fill_n algorithm:
#include <iostream> // for std::cout & std::endl
#include <sstream> // for std::stringstream
#include <algorithm> // for std::fill_n
#include <iterator> // for std::ostream_iterator
// if you just need to write it to std::cout
std::fill_n( std::ostream_iterator< const char* >( std::cout ), 2, "This is a string. " );
std::cout << std::endl;
// if you need the result as a std::string (directly)
// or a const char* (via std::string' c_str())
std::stringstream ss;
std::fill_n( std::ostream_iterator< const char* >( ss ), 2, "This is a string. " );
std::cout << ss.str();
std::cout << std::endl;
Indeed, your code is wrong.
C++ compilers treat a sequence of characters enclosed in " as a array of characters (which can be multibyte or singlebyte, depending on your compiler and configuration).
So, your code is the same as:
char str[19] = "This is a string. ";
cout<<str * 2;
Now, if you check the second line of the above snippet, you'll clearly spot something wrong. Is this code multiplying an array by two? should pop in your mind. What is the definition of multiplying an array by two? None good.
Furthermore, usually when dealing with arrays, C++ compilers treat the array variable as a pointer to the first address of the array. So:
char str[19] = "This is a string. ";
cout<<0xFF001234 * 2;
Which may or may not compile. If it does, you code will output a number which is the double of the address of your array in memory.
That's not to say you simply can't multiply a string. You can't multiply C++ strings, but you can, with OOP, create your own string that support multiplication. The reason you will need to do that yourself is that even std strings (std::string) doesn't have a definition for multiplication. After all, we could argue that a string multiplication could do different things than your expected behavior.
In fact, if need be, I'd write a member function that duplicated my string, which would have a more friendly name that would inform and reader of its purpose. Using non-standard ways to do a certain thing will ultimately lead to unreadable code.
Well, ideally, you would use a loop to do that in C++. Check for/while/do-while methods.
#include <iostream>
#include <string>
using namespace std;
int main()
{
int count;
for (count = 0; count < 5; count++)
{
//repeating this 5 times
cout << "This is a string. ";
}
return 0;
}
Outputs:
This is a string. This is a string. This is a string. This is a string. This is a string.
Hey there, I'm not sure that that would compile. (I know that would not be valid in c# without a cast, and even then you still would not receive the desired output.)
Here would be a good example of what you are trying to accomplish. The OP is using a char instead of a string, but will essentially function the same with a string.
Give this a whirl:
Multiply char by integer (c++)
cout<<"This is a string. "*2;
you want to twice your output. Compiler is machine not a human. It understanding like expression and your expression is wrong and generate an error .
error: invalid operands of types
'const char [20]' and 'int' to binary
'operator*'

C++: How to build Strings / char*

I'm new to C++. I want to make a char*, but I don't know how.
In Java is it just this:
int player = 0;
int cpu = 0;
String s = "You: " + player + " CPU: " + cpu;
How can I do this? I need a char*.
I'm focusing on pasting the integer after the string.
You almost certainly don't want to deal with char * if you can help it - you need the C++ std::string class:
#include <string>
..
string name = "fred";
or the related stringstream class:
#include <sstream>
#include <string>
#include <iostream>
using namespace std;
int main() {
int player = 0;
int cpu = 0;
ostringstream os;
os << "You: " << player << " CPU: " << cpu;
string s = os.str();
cout << s << endl;
}
if you really need a character pointer (and you haven't said why you think you do), you can get one from a string by using its c_str() member function.
All this should be covered by any introductory C++ text book. If you haven't already bought one, get Accelerated C++. You cannot learn C++ from internet resources alone.
If you're working with C++, just use std::string. If you're working with char*, you probably want to work with C directly. In case of C, you can use the sprintf function:
char* s = // initialized properly
sprintf( s, "You: %d CPU: %d", player, cpu );
Just call s.c_str( );.Here you you can see more.
PS. You can use strcpy to copy the content to new variable and then you will be able to change it.
char * means "pointer to a character".
You can create a pointer to a 'string' like this:
char* myString = "My long string";
Alternatively you can use std::string:
std::string myStdString("Another long string");
const char* myStdString.c_str();
Notice the const at the beginning of the last example. This means you can't change the chars that are pointed to. You can do the same with the first example:
const char* = "My long string";
Consider using stringstreams:
#include <iostream>
#include <sstream>
using namespace std;
int main ()
{
int i = 10;
stringstream t;
t << "test " << i;
cout << t.str();
}
It probably would have been for the best if C++ had overloaded the "+" operator like you show. Sadly, they didn't (you can though, if you want to).
There are basicly three methods for converting integer variables to strings in C++; two inherited from C and one new one for C++.
The itoa() routine. This is actually non-standard, but most compilers have it. The nice thing about it is that it returns a pointer to the string, so it can be used in functional-style programming.
sprintf(). The second holdover from C, this routine takes a destination string, a format string, and a list of parameters. How many parameters there are, and how they are interpreted depend on how the "format" string parses. This makes sprintf both immensely powerful and immensely dangerous. If you use this approach, I can pretty much guarantee you will have crash bugs your first few tries.
std::ostringstream. The C++ way. This has pretty much all the power of sprintf(), but is much safer. The drawback here is that you have to declare it, and it is not a string, so you still have to convert it to one when you are done. That means at least three lines of code are required to do anything with an ostringstream. It is also really ugly, particularly if you try any special formatting.