Strings are hard work in C.
#include <stdio.h>
int main()
{
int i;
char buf[12];
for (i = 0; i < 100; i++) {
snprintf(buf, 12, "pre_%d_suff", i); // puts string into buffer
printf("%s\n", buf); // outputs so you can see it
}
}
The 12 is enough bytes to store the text "pre_", the text "_suff", a string of up to two characters ("99") and the NULL terminator that goes on the end of C string buffers.
This will tell you how to use snprintf, but I suggest a good C book!
Strings are hard work in C.
#include <stdio.h>
int main()
{
int i;
char buf[12];
for (i = 0; i < 100; i++) {
snprintf(buf, 12, "pre_%d_suff", i); // puts string into buffer
printf("%s\n", buf); // outputs so you can see it
}
}
The 12 is enough bytes to store the text "pre_", the text "_suff", a string of up to two characters ("99") and the NULL terminator that goes on the end of C string buffers.
This will tell you how to use snprintf, but I suggest a good C book!
Use sprintf (or snprintf if like me you can't count) with format string "pre_%d_suff".
For what it's worth, with itoa/strcat you could do:
char dst[12] = "pre_";
itoa(i, dst+4, 10);
strcat(dst, "_suff");
hi,
how to combine strings and int with say two vars like:
strings1 = "monkeys"
int1 = "420"
combinedtoastring = "monkeys420"
Concatenate a string with an int. - C++ Forum
Concating String and Integer
c++ - How to concatenate a std::string and an int - Stack Overflow
Strings and Integers. Beginner question
In alphabetical order:
std::string name = "John";
int age = 21;
std::string result;
// 1. with Boost
result = name + boost::lexical_cast<std::string>(age);
// 2. with C++11
result = name + std::to_string(age);
// 3. with FastFormat.Format
fastformat::fmt(result, "{0}{1}", name, age);
// 4. with FastFormat.Write
fastformat::write(result, name, age);
// 5. with the {fmt} library
result = fmt::format("{}{}", name, age);
// 6. with IOStreams
std::stringstream sstm;
sstm << name << age;
result = sstm.str();
// 7. with itoa
char numstr[21]; // enough to hold all numbers up to 64-bits
result = name + itoa(age, numstr, 10);
// 8. with sprintf
char numstr[21]; // enough to hold all numbers up to 64-bits
sprintf(numstr, "%d", age);
result = name + numstr;
// 9. with STLSoft's integer_to_string
char numstr[21]; // enough to hold all numbers up to 64-bits
result = name + stlsoft::integer_to_string(numstr, 21, age);
// 10. with STLSoft's winstl::int_to_string()
result = name + winstl::int_to_string(age);
// 11. With Poco NumberFormatter
result = name + Poco::NumberFormatter().format(age);
- is safe, but slow; requires Boost (header-only); most/all platforms
- is safe, requires C++11 (to_string() is already included in
#include <string>) - is safe, and fast; requires FastFormat, which must be compiled; most/all platforms
- (ditto)
- is safe, and fast; requires the {fmt} library, which can either be compiled or used in a header-only mode; most/all platforms
- safe, slow, and verbose; requires
#include <sstream>(from standard C++) - is brittle (you must supply a large enough buffer), fast, and verbose; itoa() is a non-standard extension, and not guaranteed to be available for all platforms
- is brittle (you must supply a large enough buffer), fast, and verbose; requires nothing (is standard C++); all platforms
- is brittle (you must supply a large enough buffer), probably the fastest-possible conversion, verbose; requires STLSoft (header-only); most/all platforms
- safe-ish (you don't use more than one int_to_string() call in a single statement), fast; requires STLSoft (header-only); Windows-only
- is safe, but slow; requires Poco C++ ; most/all platforms
In C++11, you can use std::to_string, e.g.:
auto result = name + std::to_string( age );
So I made this and it didn't work
https://i.imgur.com/73GS95Z.png
I believe it was because on Line I tried to concatenate (is that the right term) strings with an integer???
I converted the integer into string first and this time it worked.
https://i.imgur.com/MP2octX.png
Ok. Fine.
Now I'm in the methods section of this tutorial I'm following, and the way we did it, we combined strings and integers in a single WriteLine and it still worked perfectly (see Line 22)
https://i.imgur.com/eY8A12y.png
I'm not sure why it worked this time. Can someone please explain?
ED
Thank you for the answers
ToString usage
No, you shouldn't use ToString here.
String concatenation automatically transforms non-strings into strings, which means that your two variants are nearly¹ identical:
When one or both operands are of type string, the predefined addition operators concatenate the string representation of the operands.
Source: C# Language Specification: Addition operator, MSDN.
On the other hand, the first one (without ToString):
- Is shorter to write,
- Is shorter to read,
- Is easier to maintain and:
- shows exactly the intention of the author: to concatenate strings.
So prefer the first one.
Under the hood
What is also interesting is to see what happens under the hood. One of the ways to see it is to watch the IL code within LINQPad. This program:
void Main()
{
var a = 3;
var b = " Hello";
var c = a + b;
Console.WriteLine(c);
}
is translated to the following IL:
IL_0001: ldc.i4.3
IL_0002: stloc.0 // a
IL_0003: ldstr " Hello"
IL_0008: stloc.1 // b
IL_0009: ldloc.0 // a
IL_000A: box System.Int32
IL_000F: ldloc.1 // b
IL_0010: call System.String.Concat
IL_0015: stloc.2 // c
IL_0016: ldloc.2 // c
IL_0017: call System.Console.WriteLine
See that System.String.Concat? That means that the original code can be written also like that, which translates into exactly same IL:
void Main()
{
var a = 3;
var b = " Hello";
var c = string.Concat(a, b); // This is the line which was changed.
Console.WriteLine(c);
}
When you read the documentation of string.Concat(object[]), you may learn that:
The method concatenates each object in args by calling the parameterless
ToStringmethod of that object; it does not add any delimiters.
This means that ToString is redundant. Also:
String.Emptyis used in place of any null object in the array.
Which handles nicely the case where some of the operands are null (see the footnote 1).
While in the last example, concatenation was translated into string.Concat, one should also highlight compiler optimizations:
var a = "Hello " + "World";
is translated into:
ldstr "Hello World"
stloc.0
On the other hand:
var a = string.Concat("Hello ", "World");
is translated into:
ldstr "Hello "
ldstr "World"
call System.String.Concat
stloc.0
Other alternatives
There are of course other ways to concatenate string representations of objects in C#.
StringBuilderis used when you need to do a lot of concatenation operations and helps reducing the number of intermediary strings created. Deciding whether you should use aStringBuilderor an ordinary concatenation may not be easy. Use a profiler or search for relevant answers on Stack Overflow.Using
StringBuilderhas a major drawback of making the code difficult to read and maintain. For simple cases as the one in your question,StringBuilderis not only harmful to the readability of the code, but also useless in terms of performance.string.Joinshould be used when you need to add delimiters.Obviously, never use
string.Joinwith an empty delimiter to concatenate strings.string.Formatcan be used when string templating is preferred to string concatenation. One of the cases where you may prefer that is when the message may be localized, as suggested in the answer by kunthet.Using
string.Formathas several drawbacks which makes it unsuited for simple cases like yours:With simple "{0}" placeholders, it is often unclear which parameter goes where. It is frequent to mistakenly reverse the parameters or to forget one. Luckily, C# 6 finally introduces string interpolation which solves this problem.
Runtime performance may degrade. Of course, don't assume
string.Formatis always slower. If performance matters, measure two approaches and determine which one is faster based on your actual results instead of assumptions.The code is slightly longer to write, longer to read and harder to maintain, although this is extremely minor and shouldn't bother you too much.
¹ The difference appears when one of the objects is null. Without ToString, a null is replaced by an empty string. With ToString, a NullReferenceException is thrown.
Instead, you should use string formatter. It's easier to format your number into string representation or localization. e.g.:
string expression = string.Format("Expression: {0} + {1} = {2}", a, b, sum);
More info on MSDN.
However, string formatter is less readable (and maybe also performance) than string concatenation.
unsigned concatenate(unsigned x, unsigned y) {
unsigned pow = 10;
while(y >= pow)
pow *= 10;
return x * pow + y;
}
Proof of compilation/correctness/speed
I avoid the log10 and pow functions, because I'm pretty sure they use floating point and are slowish, so this might be faster on your machine. Maybe. Profile.
z = x * pow(10, log10(y)+1) + y;
Explanation:
First you get the number of digits of the variable that should come second:
int digits = log10(y)+1; // will be 2 in your example
Then you "shift" the other variable by multiplying it with 10^digits.
int shifted = x * pow(10, digits); // will be 1100 in your example
Finally you add the second variable:
z = shifted + y; // 1111
Or in one line:
z = x * pow(10, (int)log10(y)+1) + y;