C++ 在开关中使用 int 时非常奇怪的行为
C++ Very weird behavior while using int in switch
使用以下 switch 语句我遇到了一些非常奇怪的行为:
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;
}
}
它似乎根据输入整数返回各种内容。这可能会成为一个愚蠢的错误,但到目前为止,我还没有意识到这一点。感谢任何帮助。
mti_code
和 " (Auth. Request/Repeat)"
都不是std::string
。 所以事实上,所有添加将要做的是指针添加。 因此,您最终会得到一个有点随机(并且可能无效)的指针,然后将其隐式转换为std::string
。
试试这个:
#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();
您正在添加整数和字符串文本。这在C++代码中并不完全典型。
可能发生的情况是,您返回的字符串是从无效字符指针构造的,因为文本(方式)短于 1100 个字符。
您正在尝试将整数添加到 C 样式字符串,但这不会执行预期。字符串被转换为指向其第一个字符的指针,然后该指针从字符串末尾递增 1100(或其他)字节,并进入随机内存。如果幸运的话,程序会崩溃;如果你运气不好,那么函数会返回垃圾。
可以使用字符串流来生成字符串:
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();
或者在 C++11 中,您可以使用 std::to_string
转换整数:
return std::to_string(mti_code) + " (Auth. Request/Repeat)";
您正在尝试将字符串附加到整数。这在 C 或 C++ 中是不可能的。您必须以某种方式将整数转换为字符串,std::ostringstream
推荐的方法:
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();
}
或者,如果您有支持 C++11 和 std::to_string
的编译器,则可以使用它:
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)";
}
}
您确实看到您正在将整数值添加到给定字符串文本的第一个字节的地址?这基本上是未定义的行为,因为您正在向"右"偏移 1100(因为我们谈论的是字符,这是位于内存街道上 1100 字节的地址)。例如,在我的示例中,如果我尝试将给定字符串文字的地址偏移 1100,则得到"正在初始化"。这是因为偏移地址被返回并隐式转换为一个字符串,该字符串被读取为位于给定地址的任何内容。
可以是任何东西,我的示例字符串,"疯狂的大象"或在MSVC中启用完全C++11支持的秘密方法:P。
如果我尝试再用一个字符(一个字节,向右偏移一个)来抵消它:
recognise_mti(1100); // "being initialized."
recognise_mti(1101); // "eing initialized."
整数和字符串文字与 +
连接起来。您需要先将整数转换为字符串。您可以使用stringstream
或sprintf()
执行此操作。
您正在向const char*
添加int
并将其作为string
返回。
- 为什么在全局范围内使用"extern int a"似乎不行?
- int(c) 和 c-'0' 之间的区别。C++
- 从"int*"强制转换为"unsigned int"会丢失精度错误
- 为什么野牛仍在使用"int yylex(void)",却找不到"int yylex(YYS
- 有符号的int和int-有没有一种方法可以在C++中区分它们
- 请解释这句话(cout<<1+int((a<b)^((b-a)&1) )<<endl
- 是否可以从int转换为enum类类型
- 不能在初始值设定项列表中将非常量表达式从类型 'int' 缩小到'unsigned long long'
- 向量 <int> a {N, 0} 和 int arr a[N] = {0} 的时间复杂度有什么区别
- 'short int'持有的值溢出,但"自动"不会溢出?
- 如何在C++中将一个无符号的 int 转换为两个无符号的短裤?
- 调用'begin(int [n])'没有匹配函数
- 我从int x[3]得到的一个非常奇怪的输出;
- 将非常大的 int 转换为双倍,在某些计算机上会损失精度
- 超过CPU时间限制:当MPI_Sent一个非常大的int*时
- <int> 与垫子<int>相比,犰狳SpMat非常慢
- 在 C/C++ 中将非常大的 int(写为字符串)转换为二进制字符串
- 如何仅验证int类型的输入..以一种非常简单但有效的方式?在c++中
- C++ 在开关中使用 int 时非常奇怪的行为
- CIN 一个非常大的 int 数组,段故障 11