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

时间:2015-03-23 10:44:27

标签: c++ c++11 concatenation

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

它只是不断给我堆叠。

6 个答案:

答案 0 :(得分:1)

print("die" + 1);替换为cout << std::string("die") + 1;

print()不知道如何处理字符串。使用std::cout。 &#34;模具&#34;是char*+1将递增指针。

答案 1 :(得分: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

最后,pverloading std::string + int上的运算符的标准(真的)是合法的。这绝对是一种糟糕的做法,因为你不能在std合法地做到这一点,你应该在类型的命名空间中重载运算符(所以ADL有效):这两者冲突。最重要的是,如果将来std添加了这样的+,您的代码就会开始出现奇怪的行为。最重要的是,运算符是类接口的一部分,修改一个你不“拥有”的类的接口是粗鲁的,也是一个坏习惯。

编写自己的拥有std::string的字符串类。或者是字符串视图。

最后,考虑告诉编译器使用c ++ 11,你可能只需要像-std=c++11那样传递一个标志。

答案 2 :(得分:1)

std::string s1("h1");
std::string s2("2");
s1 += s2;

如果您使用的是C ++ 11兼容编译器,则可以将int转换为字符串,如下所示:

int i = 2;
std::string s = std::to_string(i);

如果您使用的是Boost库:

#include <boost/lexical_cast.hpp>

int i = 2;
std::string s = boost::lexical_cast<std::string>(i);

请不要在C ++中使用原始字符串指针来表示字符串。

答案 3 :(得分:1)

在您自己的类型之外重载操作符最好是危险的。

只需将std::to_stringoperator++=结合使用,例如

std::string x = "hi";
x += std::to_string(2);

答案 4 :(得分:0)

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

Demo

答案 5 :(得分:-1)

"die"不是std::string。它是string literal

因此,当您向字符串文字添加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));
}

现在可行。

相关问题