将字符串分配给字符数组

问题描述 投票:0回答:9

我想知道为什么第一个语句有效,为什么第二个语句在 C++ 中不起作用

char a[10]="iqbal";  // it works

a="iqbal"; // does not work 
c++
9个回答
26
投票

严格来说,数组不是指针! 并且数组(数组的基地址)不能是可修改的左值。即它不能出现在赋值运算符的左侧。数组仅在某些情况下才会衰减为指针。阅读这篇SO post以了解数组何时衰减为指针。这是另一篇好文章,它解释了数组和指针之间的区别

另请阅读有关左值和右值的内容这里,以便您了解无法出现在

=

的 LHS 上的事物

char a[10]="iqbal";  // 它有效

在这种情况下,内部发生的事情是

a[0] = 'i';
a[1] = 'q'; 
 .
 .
a[5] = '\0';

所以一切都很好,因为

array[i]
是一个可修改的左值。

a=“iqbal”; // 不起作用

在内部,这大致相当于

0x60000(Address of a, but is a simple number here ) = Address of "iqbal"

这是错误的,因为我们无法将某些内容分配给数字。


6
投票

如果像这样初始化,则字符数组 a 将是静态的并且无法更改。无论如何,你永远不能在c中分配字符串a =“iqbal”。为此,您必须使用 strncpy 或 memcpy。否则,您将尝试覆盖指向字符串的指针,而这不是您想要的。

所以正确的代码会执行以下操作:

char a[10];
strncpy(a, "iqbal", sizeof(a) - 1);
a[sizeof(a) - 1] = 0;

-1是为终止零保留一个字节。请注意,您必须自己检查字符串是否以 null 结尾。糟糕的 API。有一个 strlcpy() 调用可以为您执行此操作,但它不包含在 glibc 中。


3
投票

第一行不是语句,而是带有初始化的声明。 第二行是带有赋值运算符的表达式语句。

不能在 C 中分配数组。

但是您可以使用字符串文字的元素初始化数组。


3
投票

为什么第一个语句有效,为什么第二个语句在 C++ 中不起作用

因为它们是不同的陈述,几乎完全无关。不要对它们都使用

=
符号这一事实感到困惑。在一种情况下,它代表对象初始化。在另一种情况下,赋值运算符。

您的第一行是合法的,因为初始化聚合(包括字符数组)是合法的。

你的第二行不合法,因为分配给数组是不合法的。

既然这是 C++,我可以建议你避免使用裸数组吗?对于字符串,请使用

std::string
。对于其他数组,请使用
std::vector
。如果你这样做,你的例子就会变成:

std::string a = "iqbal";  // it works
a="iqbal"; // so does this

1
投票

在声明后,您不能将字符串文字分配给 char 数组。

一个很好、简单且有效的替代方法是使用

std::strcpy
来执行此操作,如下所示:

struct S
{
    char name[30];
};

S s;
std::strcpy( s.name,
    "The moribunds salute you." );

0
投票

写作时 字符 a[10]="iqbal" 您正在使用字符初始化字符数组 a 的元素。我们可以对 int 类型执行相同的操作(请注意,char 类型的处理方式略有不同): int a[10]={1,2,...};

但是在声明部分之后编写以下内容将是无效的,因为 a 将被视为指针。所以写一些类似的东西 a={1,2,...}; 或a=“iqbal” 没有任何意义!


0
投票

尝试:

char a[10]="iqbal";
char *my_a = a;

并与 my_a 一起工作。


0
投票

在 C++11 中,你可以使用 lambda 来进行初始化,如下所示:

bool test = true;
/*const*/ char a[10] = { //Aggregate initialization
                        [=] //capture by value
                           ()//no parameters
                             { //start lambda
    switch (test) {
        case true: return *"test=true"; //*"xxx" don't return a pointer, but the 'string' itself
        case false: return *"test=false"; 
    } //switch
}()};  //}, close the lambda, (), call it, }; close aggregate initialization

当您的环境不支持

std::string
(例如 NVidia 的 CUDA 或一些奇怪的嵌入式环境)时,这会派上用场。 lambda 被内联,因此在内部它会转换为
char a[10] = test?"xxx":"yyy";

如果您可以选择这样做,那么您显然希望始终使用

std::string
,因为固定大小的字符缓冲区从根本上来说是一个坏主意。

如果您使用

std::string
,您可以使用:
chararray = mystring.c_str();
将其转换为字符数组。如果您坚持使用
printf
,这很有用:
printf("s = %s", mystring.c_str());


0
投票

strncpy_s() 适用于 CPP;

char dst[7];
strncpy_s(dst, 7, "Hello, world!", 6);
// above can also be
strncpy_s(dst, 7, "Hello, world!", _TRUNCATE);
© www.soinside.com 2019 - 2024. All rights reserved.