如何在C++中正确分配char*?

3

我的c++代码看起来像这样:

char* x;
    switch(i){ 
        case 0:
            x = '0';
        case 1:
            x = "1";
        ...}

我无法弄清楚如何使它工作,因为在第一个 x = '0'; 处编译器会报错:

error: invalid conversion from ‘char’ to ‘char*’

对于第二个x = "1";,编译器报错:

warning: deprecated conversion from string constant to ‘char*’

我在这里应该做什么?我是否完全走错了方向?

这段内容与IT技术无关。

我正在努力弄清楚如何将这些值分配给一个char*,然后在之后使用strcat()函数。 - wfbarksdale
x将会是strcat的第一个参数还是第二个参数?如果它将作为第一个参数,那么在得到这个答案之后,你很有可能还会有另一个问题。 - Robᵩ
最终,我将所有东西都设为char,然后在strcat中使用了&x,结果成功了,非常感谢大家。 - wfbarksdale
6个回答

4
case 0 中,您试图将 x 设置为一个字符 (类型为 char),但在 case 1 中,您试图将 x 设置为 C 字符串 (类型为 char const[2])。这是引号的类型造成了差异;单引号用于字符,双引号用于 C 风格的字符串。
如果您想要两次都设置为字符串,请在 x = '0' 中的 0 周围加上双引号。
如果您想要将 x 设置为字符,请两次使用单引号并解除指针引用,如 *x,以使其变为 *x = '0'*x = '1',或者将 x 的类型从 char* (字符指针)更改为 char (字符)。然后您不必进行解引用操作。
再一次地,如果您想要将 x 设置为字符串,最好使用 C++ 字符串而不是 C 字符串,使用双引号就像 C 字符串一样,但您将获得自动内存管理、边界检查和所有成员函数等众多额外功能。
char* x = new char;

或者通过在堆栈上创建 char

char c;
char* x = &c;

重要提示:

如果您打算在稍后使用strcat(或任何期望C字符串的函数)与char*一起使用,则必须正确地NULL终止缓冲区。因此,您需要按照以下方式执行:

char x[2] = {}; // on the stack, filled with NULLs
                // use a bigger number if you need more space

或者

char* x = new char[2]; // on the heap, use more than 2 if you're
                       // storing more than 1 character
x[1] = NULL; // set the last char to NULL

如果你不这么做,如果你不幸的话,你会得到垃圾数据,如果你幸运的话,你可能会得到一个段错误。
然后在声明x之后,你可以执行*x = '0'或其他操作。
如果你决定使用new[],请确保使用相应的delete[]释放内存。

2
我要补充一点,要使用*x = '0'char * x 的声明是不够的(请参考下面的其他答案)。 - Nicolas Grebille

3

与普遍观念相反,char*并不是字符串,建议使用std::string代替。

#include <string>

std::string x;
switch(i){ 
    case 0:
        x = "0";
    case 1:
        x = "1";
    ...}

1
很好的声誉计数 :) 它也是一个字符串。所以如果我们这样说,double 可以是一个字符串。 - Seth Carnegie
1
我只想补充一点,如果你不是要存储一个字符串,而只是一个字符,那么在这个答案里将std::string替换为char,双引号替换为单引号也可以起作用。 - jedwards
@Seth: 在 const char * x = "foo"; 中,"foo" 是一个字符串字面值,而 x 指向一个以 0 字节结尾的字节块。x 不是一个字符串,它是指向常量字符数组的指针。std::string 提供真正的字符串操作。 - André Caron
非常愿意这样做,但之后要将x传给strcat函数(嗯嗯嗯)。所以我需要它是一个char*类型的变量。 - wfbarksdale
2
@Andre 嗯,无所谓。在 C 中它是一个字符串,在 C++ 中也是一个 C 字符串。因为它是一串字符。 - Seth Carnegie
显示剩余5条评论

2
如果你要使用char*,你需要为字符串分配空间,可以通过将x的声明更改为以下内容来实现:
char x[10]; // allocate a fixed 10-character buffer

或者在堆上动态分配空间:
x = new char[10]; // allocate a buffer that must be deleted later

那么你可以使用:

strcpy(x, "1"); // Copy the character '1' followed by a null terminator
                // into the first two bytes of the buffer pointed to by x.

将字符串"1"复制到指向x的缓冲区中。如果您使用第二个示例,则必须稍后执行以下操作:

delete x;

当然,如果你真的想处理字符串,有更好的方法,处理单个字符也有更好的方法(请参见其他答案)。

2
这只是一条注释而不是回答,但你可以使用以下方法从整数中获取字符01等:
char x = '0' + i;

这样可以避免使用 switch 语句(当然,i 的范围是 0 <= i <= 9)。


你确定这个能工作吗?对我来说似乎不起作用,但也许是我在其他地方出了问题。 - wfbarksdale
@weezybizzle 我几乎确定这应该可以工作,是的。问题确切是什么? - Nicolas Grebille
它在程序中稍后的位置,我已经解决了。谢谢你这个巧妙的技巧! - wfbarksdale

1
首先,请找出一种可以使用std::string的方法。如果您继续选择的这条路,那么您肯定会创建出有缺陷的程序。
话虽如此,以下是您的答案:您如何声明x以及如何对其进行赋值,在很大程度上取决于您之后如何使用它。以下是一个示例:
#include <stdio.h>
int main(int ac, char **av) {
  const char* x;      
  switch(ac) {
  case 0:
    x = "0";
    break;
  case 1:
    x = "1";
    break;
  default:
    x = "DANGER!";
    break;
  }
  printf("%s\n", x);
  return 0;
}

在这个第一个例子中,我们将指针 x 设置为指向三个可能的 const char 数组之一。我们可以稍后从这些数组中读取(如在 printf 调用中),但我们永远不能写入这些数组。
或者,如果您希望创建一个稍后可以写入的数组:
#include <stdio.h>
#include <string.h>
int main(int ac, char **av) {
  char x[32]; // make sure this array is big enough!     

  switch(ac) {
  case 0:
    strcpy(x, "0");
    break;
  case 1:
    strcpy(x, "1");
    break;
  default:
    strcpy(x, "NOT 0 nor 1:");
    break;
  }

  strcat(x, ", see?");
  printf("%s\n", x);
  return 0;
}

编辑:从第二个示例中删除错误的const


1
你正在声明一个char 指针,但没有分配任何空间,然后试图将字符分配给它。
char x;

会给你一个类型为char的变量

char *x = new char[10]; 

会给你一个由char指针指向的10个字节内存的指针。

正如André Caron上面所指出的,既然你正在使用c++,你真的应该使用实际的字符串来使你的生活更轻松。


请确保在分配数组后正确地将其以NULL结尾。 - Seth Carnegie

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接