【问题标题】:const char* concatenationconst char* 连接
【发布时间】:2010-12-31 23:46:18
【问题描述】:

我需要像这样连接两个 const 字符:

const char *one = "Hello ";
const char *two = "World";

我该怎么做呢?

我从具有 C 接口的第三方库中传递了这些 char*s,因此我不能简单地使用 std::string

【问题讨论】:

  • 我很困惑 - 最初的提问者写了“c++”标签 - 然后其他人删除了它。这个问题的现状如何?是否允许使用 C++ 代码?
  • @Johannes:这是一个更好的问题 xD。
  • 另请注意原始问题没有提到 C - 我已经删除了该标签。
  • 我将 C++ 标签切换为 C,因为 OP 接受了使用堆栈上的数组和 strcpystrcat 调用的答案,我认为更改标签是有意义的。
  • 添加了 C C++标签。正如 OP 在评论中解释的那样,他正在编写 C++ 代码,但调用了一个使用 C 接口的库。这个问题与两种语言都相关。

标签: c++ c string-concatenation


【解决方案1】:

在您的示例中 onetwo 是 char 指针,指向 char 常量。您不能更改这些指针指向的 char 常量。所以像这样的:

strcat(one,two); // append string two to string one.

不会工作。相反,您应该有一个单独的变量(char 数组)来保存结果。像这样的:

char result[100];   // array to hold the result.

strcpy(result,one); // copy string one into the result.
strcat(result,two); // append string two to the result.

【讨论】:

  • char* 结果怎么样;结果 = calloc(strlen(one)+strlen(two)+1, sizeof(char));然后是 strcpy+strcat?
  • @luiscubal:是的,这也可以......只需使用 (char*) 强制转换,因为 calloc 返回 void*
  • 这个答案的问题是硬编码的数组大小。这是一个非常糟糕的习惯,尤其是如果您不知道“一”和“二”的大小。
  • 在第一个示例中,strcpy(one,two); 应该是 strcat(one,two);(不是 that 使它正确,正如您正确指出的那样)。
  • sprintf(dest,"%s%s",one,two) 怎么样,忘记副本?
【解决方案2】:

C 方式:

char buf[100];
strcpy(buf, one);
strcat(buf, two);

C++ 方式:

std::string buf(one);
buf.append(two);

编译时方式:

#define one "hello "
#define two "world"
#define concat(first, second) first second

const char* buf = concat(one, two);

【讨论】:

  • 值得一提的是,“编译时”方式只有在onetwo都是字符串字面量时才有效。
【解决方案3】:

如果您使用的是 C++,为什么不使用 std::string 而不是 C 风格的字符串?

std::string one="Hello";
std::string two="World";

std::string three= one+two;

如果您需要将此字符串传递给 C 函数,只需传递 three.c_str()

【讨论】:

  • 因为我使用的是用 C 编码的库,所以函数返回 const char *
  • @AnthoniCaldwell:谢谢你的笑声。因为工作压力,我不能。:D
  • @AnthoniCaldwell 每个 C++ 开发人员共同的噩梦:不得不使用 C 库及其 const char *s...
【解决方案4】:

使用std::string

#include <string>

std::string result = std::string(one) + std::string(two);

【讨论】:

  • 不需要第二次显式构造函数调用
【解决方案5】:
const char *one = "Hello ";
const char *two = "World";

string total( string(one) + two );

// to use the concatenation as const char*, use:
total.c_str()

更新:已更改 string total = string(one) + string(two);string total( string(one) + two ); 出于性能原因(避免构造字符串二和临时字符串总数)

// string total(move(move(string(one)) + two));  // even faster?

【讨论】:

  • @iburidu 你量过吗?在安全胜过性能的情况下呢? (它们是常见的情况)
  • @Sqeaky 绝对没有比任何其他解决方案更安全的情况,但它总是比编译时解决方案慢,通过调用运行时行为以及几乎可以肯定调用内存分配。跨度>
【解决方案6】:

再举一个例子:

// calculate the required buffer size (also accounting for the null terminator):
int bufferSize = strlen(one) + strlen(two) + 1;

// allocate enough memory for the concatenated string:
char* concatString = new char[ bufferSize ];

// copy strings one and two over to the new buffer:
strcpy( concatString, one );
strcat( concatString, two );

...

// delete buffer:
delete[] concatString;

但除非您特别不想或不能使用 C++ 标准库,否则使用 std::string 可能更安全。

【讨论】:

  • 如果 OP 不能使用 C++,他就不能使用new。如果他可以使用它,他应该使用std::string,就像你说的那样。
【解决方案7】:

您似乎正在使用带有 C 库的 C++,因此您需要使用 const char *

我建议将const char * 包装成std::string

const char *a = "hello "; 
const char *b = "world"; 
std::string c = a; 
std::string d = b; 
cout << c + d;

【讨论】:

    【解决方案8】:

    首先,您必须创建一些动态内存空间。然后,您可以将两个字符串 strcat 到其中。或者您可以使用 c++“字符串”类。老式的 C 方式:

      char* catString = malloc(strlen(one)+strlen(two)+1);
      strcpy(catString, one);
      strcat(catString, two);
      // use the string then delete it when you're done.
      free(catString);
    

    新的 C++ 方式

      std::string three(one);
      three += two;
    

    【讨论】:

    • 为什么需要动态内存?
    • -1 对我来说,首先是你需要使用 malloc 和 free 的 C 方式。那么即使你做 new 那么它应该是 delete[] 而不是 delete。
    • 我使用的库是用 C 而不是 C++ 编码的,所以所有函数都返回 const char * 而不是字符串。
    • @Naveen,标签上写着“C++”。如果你不能使用new和delete,那么他就不应该使用C++标签。
    【解决方案9】:

    如果你不知道字符串的大小,你可以这样做:

    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    
    int main(){
        const char* q1 = "First String";
        const char* q2 = " Second String";
    
        char * qq = (char*) malloc((strlen(q1)+ strlen(q2))*sizeof(char));
        strcpy(qq,q1);
        strcat(qq,q2);
    
        printf("%s\n",qq);
    
        return 0;
    }
    

    【讨论】:

      【解决方案10】:

      您可以使用strstream。它已正式弃用,但我认为,如果您需要使用 C 字符串,它仍然是一个很棒的工具。

      char result[100]; // max size 100
      std::ostrstream s(result, sizeof result - 1);
      
      s << one << two << std::ends;
      result[99] = '\0';
      

      这会将one 然后two 写入流中,并使用std::ends 附加一个终止\0。如果两个字符串最终都可以精确地写入 99 字符 - 所以不会留下空格来写入 \0 - 我们在最后一个位置手动写入一个。

      【讨论】:

      • 弃用不应该太重要。即使它从标准的未来版本中删除,在您自己的命名空间中重新实现也不是很多工作。
      • @Steve,确实 :) 编写自己的 streambuf 将输出定向到与 ostream 一起使用的字符缓冲区也不是太难。
      【解决方案11】:
      const char* one = "one";
      const char* two = "two";
      char result[40];
      sprintf(result, "%s%s", one, two);
      

      【讨论】:

        【解决方案12】:

        在动态分配内存时不使用strcpy命令连接两个常量char指针:

        const char* one = "Hello ";
        const char* two = "World!";
        
        char* three = new char[strlen(one) + strlen(two) + 1] {'\0'};
        
        strcat_s(three, strlen(one) + 1, one);
        strcat_s(three, strlen(one) + strlen(two) + 1, two);
        
        cout << three << endl;
        
        delete[] three;
        three = nullptr;
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2018-11-03
          • 2016-07-23
          • 1970-01-01
          • 1970-01-01
          • 2016-05-12
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多