自动连接字符串和 int C++
Automatically Concatenate Strings and Int C++
在Lua中(抱歉,我最喜欢使用它(,int和string之间的转换是自动完成的,所以
"hi"..2
将结果为
"hi2"
在C++(因为我似乎无法获得默认的 C++11 stoi()
和to_string()
方法工作(,我为自己定义了这些:
int stoi(string str) {
char* ptr;
strtol(str.c_str(), &ptr, 10);
}
string to_string(int i) {
char* buf;
sprintf(buf, "%d", i);
return buf;
}
无论如何,这基本上就是默认定义的方式。
然后我做了这个:
string operator+ (string& stuff, int why) {
stuff.append(to_string(why));
}
我在以下代码上尝试了它:
void print(string str) {
cout << str << endl;
}
int main() {
cout << stoi("1") + 2 << endl;
print("die" + 1);
return 0;
}
它输出
3
ie
为什么会这样,我该如何解决?
编辑:代码现在的样子如下:
using namespace std;
string to_string(int i) {
char* buf;
sprintf(buf, "%d", i);
return buf;
}
string operator+ (string stuff, int why) {
stuff.append(to_string(why));
return stuff;
}
int main() {
cout << string("die") + 2 << endl;
return 0;
}
它只是不断给我堆栈转储。
将print("die" + 1);
替换为cout << std::string("die") + 1;
print()
不知道如何处理字符串。使用 std::cout
."die"是一个char*
,+1
指针会递增。
std::string to_string(int i) {
char buf[(sizeof(int)*CHAR_BIT+2)/3+3];
sprintf(buf, "%d", i);
return buf;
}
您需要制作要打印到的实际缓冲区。 数学是对大 最大的小数int
的快速高估 字符;3 位可以容纳 1 个十进制字符,加上 null,加上否定,加上舍入,加上 1 表示良好的度量。 希望我没有犯错:做一些测试。
同时使用 snprintf
而不是 sprintf
当你使用它时:缓冲区溢出是不可玩弄的。
接下来的问题是"hello"
不是std::string
,而是char const[6]
——6 char
的数组。 它可以转换为 tom std::string
,但+1
会将其转换为指向第一个字符的指针,然后将其+1
为第二个字符。
投射到之前std::string
。
最后,在标准(实际上(将运算符加载到合法std::string + int
上是模棱两可的。 这绝对是不好的做法,因为您无法合法地std
这样做,并且您应该在类型的命名空间中重载运算符(因此 ADL 有效(:这两者冲突。 最重要的是,如果将来std
添加这样的+
,您的代码将开始表现得很奇怪。 最重要的是,运算符是类接口的一部分,修改你不"拥有"的类的接口是粗鲁的,也是一个坏习惯。
编写自己的字符串类,该字符串类拥有std::string
。 或字符串视图。
最后,考虑告诉你的编译器使用 c++11,你可能只需要像 -std=c++11
一样给它传递一个标志。
std::string s1("h1");
std::string s2("2");
s1 += s2;
如果您使用的是兼容C++11的编译器,则可以像这样将int转换为字符串:
int i = 2;
std::string s = std::to_string(i);
如果您使用的是速推库:
#include <boost/lexical_cast.hpp>
int i = 2;
std::string s = boost::lexical_cast<std::string>(i);
请不要在字符串C++中使用原始字符指针。
载运算符+,而不是您自己的类型,它充其量是危险的。
只需将std::to_string
与operator+
或+=
结合使用,例如
std::string x = "hi";
x += std::to_string(2);
C++14 引入了一个用户定义的文本,该文本采用字符串文本(应用转换以使其成为指针(并返回std::string
。在 C++11 中,你可以自己编写(这取自 libstdc++(:
inline std::string
operator""_s(const char* str, size_t len)
{
return std::string{str, len};
}
(注意:不带前下划线的 UDL 是保留名称(
你可以像这样使用它:
// Assumes operator+ is overloaded
print("die"_s + 1);
演示
"die"
不是std::string
。这是一个字符串文字。
因此,当您将 1 添加到字符串文本时,它会衰减为const char*
,而+ 1
只是将该指针递增 — 到下一个字符,'i'
。
然后,使用递增的指针调用print
,这会导致使用该指针构造std::string
。由于它指向'i'
字符,因此构造字符串初始化为"ie"
。
您必须首先从字符串文字中创建一个std::string
,以使其调用您的operator+
:
std::cout << std::string("die") + 1;
然后对您的operator+
进行一些修复:
string operator+ (string stuff, int why) {
return stuff.append(to_string(why));
}
现在它起作用了。
- 为什么在全局范围内使用"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[]中的foreach
- 在c++中访问int到类对象的映射时出错
- 为什么我无法更改"set<set>"循环中的值<int>
- 长 长 int 不要 长 int 好
- C++程序在循环后给出奇怪的int值
- 如何计算数据类型的范围,例如int
- 如果"new int"返回"int*",那么为什么"new int[n]"不返回"int**"?
- 如何在cpp.中使用协议缓冲区存储大缓冲区/数组(char/int)