Reputation: 23
I'm getting some very strange behaviour using the following switch statement:
string recognise_mti(int mti_code)
{
switch(mti_code)
{
case 1100:
case 1101:
return (mti_code + " (Auth. Request/Repeat)"); break;
default:
return (mti_code + " (NOT RECOGNISED)"); break;
}
}
It seems to return all sorts of things depending on the input integer. It's probably going to turn out to be a silly mistake but as of yet, I'm unable to recognise it. Appreciate any help.
Upvotes: 0
Views: 387
Reputation:
You do see that you're adding an integer value to an address of the first byte of a given string literal? This is basically undefined behavior, since you're making an offset of, let's say, 1100 to the "right" (since we're talking about chars, that's the address of something located 1100 bytes down the memory street). For example, in my example, if I try to offset the given string literal's address by 1100, I get "being initialized." That's because the offset address is returned and implicitly converted into a string which gets read as whatever is located at the given address.
Could be anything, my example string, "crazy elephants" or the secret way to enable full C++11 support in MSVC. :P
If I were to try to offset it by one more char (one byte, one offset to the right):
recognise_mti(1100); // "being initialized."
recognise_mti(1101); // "eing initialized."
Upvotes: 1
Reputation: 272487
Neither mti_code
nor " (Auth. Request/Repeat)"
is a std::string
. So in fact, all that addition is going to do is pointer addition. So you'll end up with a somewhat random (and probably invalid) pointer, which is then implicitly converted to a std::string
.
Try this:
#include <sstream>
...
std::stringstream ss;
ss << mti_code;
switch(mti_code)
{
case 1100:
case 1101:
ss << " (Auth. Request/Repeat)"; break;
default:
ss << " (NOT RECOGNISED)"; break;
}
return ss.str();
Upvotes: 10
Reputation: 409166
You are trying to append a string to an integer. That is not possible in C or C++. You have to convert the integer to a string somehow, std::ostringstream
is the recommended way:
std::string recognise_mti(const int mti_code)
{
std::ostringstream ostr;
switch(mti_code)
{
case 1100:
case 1101:
ostr << mti_code << " (Auth. Request/Repeat)";
break;
default:
ostr << mti_code << " (NOT RECOGNISED)";
break;
}
return ostr.str();
}
Or if you have a compiler supporting C++11 and std::to_string
you can use that:
std::string recognise_mti(const int mti_code)
{
switch(mti_code)
{
case 1100:
case 1101:
return std::to_string(mti_code) + " (Auth. Request/Repeat)";
default:
return std::to_string(mti_code) + " (NOT RECOGNISED)";
}
}
Upvotes: 2
Reputation: 254441
You're trying to add an integer to a C-style string, which doesn't do what you expect. The string is converted to a pointer to its first character, and then that pointer is incremented by 1100 (or whatever) bytes, off the end of the string, and into random memory. If you're lucky, the program will crash; if you're unlucky, then the function will return garbage.
You could use a string stream to build the string:
std::ostringstream result;
switch(mti_code)
{
case 1100:
case 1101:
result << mti_code << " (Auth. Request/Repeat)"; break;
default:
result << mti_code << " (NOT RECOGNISED)"; break;
}
return result.str();
or in C++11, you could use std::to_string
to convert the integer:
return std::to_string(mti_code) + " (Auth. Request/Repeat)";
Upvotes: 2
Reputation: 52519
You're adding an int
to a const char*
and returning that as a string
.
Upvotes: 0
Reputation: 13842
You can't concatenate an integer and a string literal with +
. You need to convert the integer to a string first. You can do this with a stringstream
or with sprintf()
.
Upvotes: 0
Reputation: 399803
You are adding an integer and a string literal. That's not exactly typical in C++ code.
What is likely happening is that you're returning a string constructed from an invalid character pointer, since the literals are (way) shorter than 1100 characters.
Upvotes: 4