字符串文字和字符文字可以连接吗?

时间:2009-03-11 18:38:06

标签: c# java c++ string char

为什么name在以下C ++代码中出错?

string name =  "ab"+'c';

等效代码在Java / C#中的表现如何?

8 个答案:

答案 0 :(得分:13)

尝试

std::string name = "ab" "c";

std::string name = std::string("ab") + c;

在C ++中,“ab”不是std::string,而是指向字符串的指针。向指针添加整数值时,会得到一个新指针,指向字符串的下方:

char *foo = "012345678910121416182022242628303234";
std::string name = foo + ' '; 

name被设置为“3234”,因为''的整数值是32,并且在foo开头之后的32个字符是字符串结尾之前的四个字符。如果字符串较短,则您将尝试访问未定义内存区域中的内容。

解决方法是从字符数组中生成std:string。 std:strings允许您按预期将字符附加到它们:

std::string foo = "012345678910121416182022242628303234";
std::string name = foo + ' '; 

name设置为“012345678910121416182022242628303234”

答案 1 :(得分:8)

问题是“ab”不是C ++ std::string,而是const char[3]。 所以它正在寻找的+运算符是operator+ (const char[3], char)。这不存在,因此编译器会尝试让数组衰减到指针,因此它会查找operator+ (const char*, char)。这是存在的,所以编译器会选择它,但它做错了。将一个整数值(char)添加到指针(const char *)是一个很常见的操作,显然,这就是这个operator +的作用。理解这一点的关键是要意识到第一个参数是1)一个数组,2)每当数组没有意义时的指针。它在C中也被用作字符串,是的,但它不是字符串。它是一个指针(或偶尔,一个数组)。

operator+ (const std::string&, char)连接,但编译器甚至不会查找它,因为第一个参数不是std :: string。

所以解决方案是手动创建字符串:

string name = std::string("ab")+'c';

现在编译器可以找出正确的operator +来调用。

答案 2 :(得分:5)

在C ++中,编译器正在寻找具有此原型的函数:

T operator+ (const char*, char);

由于没有一个,它无法弄清楚T是什么并且无法解析operator<<调用,因此它回退到唯一的解决方案:指针添加。在Josh的答案中连接到字符串没有问题,因为它存在一个函数。

答案 3 :(得分:3)

给出C ++代码:

std::string name =  "ab"+'c';

Java中的等价物是:

String name = "ab".substring('c');

两者都将char提升为int。当然在Java中,它会进行范围检查,因此会引发异常。在C ++中,你只是得到了未定义的行为(或者某些)。

答案 4 :(得分:2)

Java:

public class Main
{
    public static void main(String[] args)
    {
        System.out.println("AB" + 'c');
    }
}

输出是:

  

ABC

编辑:

实际上编译器硬编码String ABc ...

如果你做“AB”+ argv [0] .charAt(0);为了使它使用变量然后编译器执行此操作(基本上):

StringBuilder b = new StringBuilder;
b.append("AB");
b.append(argv[0].charAt(0));
System.out.println(b.toString());

答案 5 :(得分:1)

你可以在C#中连接字符串和字符 - 它不像C ++那么严格。

这在C#中运行得很好:

string test = "foo" + 'b';

答案 6 :(得分:1)

C ++编译器不会自动将字符串文字与字符文字连接起来。但它会将字符串文字相互连接起来。语法如下:

const char * cs = "ab" "c"; // append string-literals

正如其他人所提到的,string不是内置的 C ++语言类型。但是C ++标准库中有string类型。以下是一些使用示例:

#include <string>
const char * cs = "ab" "c";
std::string s1( cs );
std::string s2( "ab" "c" );
std::string s3 = "ab" "c";

答案 7 :(得分:1)

嗯,我通常在C ++中会做的是

string name = string(“ab”)+'c';

请记住,文字“ab”是不是类型字符串。你正在做的是希望char数组和字符之间没有“+”,然后希望编译器能以某种方式注意到你真的希望结果是一个std :: string,然后解析你的表达式隐式转换的某些组合的右侧,可以与运算符组合以生成该类型的结果。对我来说似乎是一个相当高的命令。

无论如何,没关系。你会看到,在C中,数组和指针之间的唯一区别是它们的内存是如何分配的。一旦你有一个,你基本上有一个“数组/指针的东西”。因此,“+”是在所有数组和指针上定义的运算符,它接受任何整数类型的另一个参数并执行指针数学运算,返回指向该点之后的许多元素的指针。另外,在C“char”中实际上只是另一种整数类型。这些C设计决策都是有用的 hacks ,但与黑客经常发生的情况一样,它们与直观的意外结果相结合。因此,所有“ab”+“c”为你做的是返回99字节的地址,而“ab”字面值恰好存储在内存中。

有时你可以依赖隐式转换,但你真的必须准备好在其他时候帮助你的编译器。