代码之家  ›  专栏  ›  技术社区  ›  yesraaj

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

  •  4
  • yesraaj  · 技术社区  · 17 年前

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

    string name =  "ab"+'c';
    

    在爪哇/C中等效码的行为如何?

    8 回复  |  直到 14 年前
        1
  •  13
  •   Salman A    17 年前

    尝试

    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个字符是字符串结尾之前的4个字符。如果字符串较短,您将尝试访问未定义内存区域中的某些内容。

    解决方法是从字符数组中生成一个std:string。std:strings允许您按预期向它们追加字符:

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

    名称 设置为“012345678910121416182022242628303234”

        2
  •  8
  •   fredoverflow    14 年前

    问题是“ab”不是C++。 std::string 但A const char[3] . 所以它要找的+运算符是 operator+ (const char[3], char) . 它不存在,因此编译器试图让数组衰减到指针,因此它查找 operator+ (const char*, char) . 它存在,所以编译器选择它,但它做了错误的事情。将整数值(char)添加到指针(const char*)是一个足够常见的操作,显然,这就是这个操作符+所做的。理解这一点的关键是要认识到,第一个参数是1)数组,以及2)数组不合理时的指针。它在C中也用作字符串,是的,但它不是字符串。它是一个指针(或者偶尔是一个数组)。

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

    因此,解决方案是手动创建字符串:

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

    现在编译器可以找到正确的运算符+来调用。

        3
  •  5
  •   greyfade    17 年前

    在C++中,编译器正在用这个原型寻找函数:

    T operator+ (const char*, char);
    

    因为没有一个,它无法找出什么不是,也无法解决 operator<< 调用,所以返回到唯一剩下的解决方案:指针添加。在josh的答案中,与字符串联系是没有问题的,因为它有一个函数。

        4
  •  3
  •   Tom Hawtin - tackline    17 年前

    给定C++代码:

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

    Java中的等价物是:

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

    这两种方法都会促进char到int。当然,在Java中,它会进行范围检查,从而引发异常。在C++中,你只会得到未定义的行为(或一些行为)。

        5
  •  2
  •   TofuBeer    17 年前

    爪哇:

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

    输出为:

    abc

    编辑:

    实际上编译器硬编码字符串abc…

    如果执行“ab”+argv[0].charat(0);使其使用变量,则编译器将执行以下操作(基本上):

    StringBuilder b = new StringBuilder;
    b.append("AB");
    b.append(argv[0].charAt(0));
    System.out.println(b.toString());
    
        6
  •  1
  •   Apocalisp    17 年前

    你可以把C和C中的字符串和字符串起来,我猜它不像C++那样严格。

    这在C中很有效:

    string test = "foo" + 'b';
    
        7
  •  1
  •   jwfearn    17 年前

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

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

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

    #include <string>
    const char * cs = "ab" "c";
    std::string s1( cs );
    std::string s2( "ab" "c" );
    std::string s3 = "ab" "c";
    
        8
  •  1
  •   T.E.D.    17 年前

    嗯,我通常在C++中做什么

    字符串名称=字符串(“ab”)+“c”;

    记住文字“ab”是 字符串类型。您所做的是希望在char数组和char之间没有“+”,然后希望编译器可以不知何故地注意到您真的希望结果是一个std::string,然后分析右侧的表达式以获得一些隐式转换的组合,这些隐式转换可以与用于produc的运算符组合在一起。e这类结果。对我来说似乎是个很高的要求。

    不管怎样,这并不重要。在C语言中,数组和指针的唯一区别就是它们的内存分配方式。一旦你有了一个,你基本上就有了一个“数组/指针的东西”。因此“+”是一个在所有数组和指针上定义的运算符,它接受任何整数类型的另一个参数,并进行指针数学运算,返回指向该点之后的许多元素的指针。而且,在C中,“char”实际上只是另一种整数类型。这些C设计决策都很有用 黑客 但是,正如黑客经常发生的那样,它们与直观的意外结果结合在一起。所以“ab”+“c”所做的就是返回一个地址99个字节,而“ab”字恰好存储在内存中。

    有时您可以依赖于隐式转换,但您必须做好准备,以便在其他时候帮助编译器。