自动连接字符串和 int C++

Automatically Concatenate Strings and Int C++

本文关键字:int C++ 字符串 连接      更新时间:2023-10-16

在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_stringoperator++=结合使用,例如

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));
}

现在它起作用了。