【问题标题】:difference between character array initialized with string literal and one using strcpy用字符串字面量初始化的字符数组和使用 strcpy 初始化的字符数组之间的区别
【发布时间】:2015-01-31 13:47:58
【问题描述】:

请帮助我了解使用 char line[80]="1:2" 之类的初始化字符数组(不起作用!!)和使用 char line[80] 后跟 strcpy(line,"1:2") 的区别。
根据我在第一种情况下的理解,我有一个字符数组,它已经分配了内存,我正在向它复制一个字符串文字。在第二种情况下也是如此。但显然我错了。那么我的理解有什么问题。

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
void tokenize(char* line)
{
   char* cmd = strtok(line,":");

    while (cmd != NULL)
    {
    printf ("%s\n",cmd);
    cmd = strtok(NULL, ":");
    } 
}

int main(){
char line[80]; //char line[80]="1:2" won't work 
/*
char *line;
line = malloc(80*sizeof(char));
strcpy(line,"1:2");
*/
strcpy(line,"1:2");
tokenize(line);
return 0;
}

【问题讨论】:

  • 因为它是char数组,所以初始化时的值应该是{'1',':','2'};。在一个索引处,只会添​​加一个字符值。
  • char line[80]="1:2" 是字符串文字,你不能在tokenize 函数中修改它(使用strtok)所以它不起作用。
  • char line[80]="1:2" --> char line[80]="1:2";

标签: c pointers token c-strings


【解决方案1】:

你错了。这两个代码sn-ps的结果

char line[80] = "1:2";

char line[80];
strcpy( line, "1:2" );

是一样的。就是这样的说法

char line[80] = "1:2";

确实有效。:) 只有一个区别。当数组由字符串字面量初始化时,数组中没有字符串字面量的相应初始化字符的所有元素都将由'\0' 初始化,即它们将被零初始化。而当使用函数strcpy 时,数组中未被字符串文字的字符覆盖的元素将具有未确定的值。

数组由字符串字面量初始化(除了它的“尾部”的零初始化),就像应用函数strcpy一样。

这些语句之间存在结果的精确等价

char line[80] = "1:2";

char line[80];
strncpy( line, "1:2", sizeof( line ) );

即使用函数strncpy 并指定目标数组的大小。

如果您的意思是直接将字符串文字作为函数的参数传递给函数tokenize,那么程序具有未定义的行为,因为您可能无法更改字符串文字。

根据 C 标准(6.4.5 字符串文字)

7 不确定这些数组是否不同,前提是它们的 元素具有适当的值。 如果程序试图 修改这样的数组,行为未定义。

【讨论】:

  • 我认为 OP 可能会说 tokenize(line); 函数不能通过使用字符串文字来工作。当然它也不能使用字符串文字,因为它是常量字符串并且修改它是非法的。
  • strncpy() 在以下任一情况下停止复制:1) 源字符串当前字符为 '\0' 2) 达到大小参数。当满足第一个(任一)条件时,复制将停止。所以这两种初始化数组的方法是不等价的
  • @user3629249 你错了。阅读 strncpy 的描述。
  • 您好 user3629249 是的,我猜你想表达什么。就像你可以拥有 arr[80]="1:2:3:\0:4:5"。正如 VladfromMoscow 所说,在这种情况下, arr 将包含所有 6 个字符,后跟 \0 的尾部,如果我使用 strcpy(arr,"1:2:3:\0:4:5") 正如@you 指出的那样,我只会复制“1:2:3:\ 0”,然后其余76个元素都将具有未确定的值所以我相信VladfromMosco也是正确的,但您也讨论了极端情况,澄清了strcpy何时无法具有类似的行为。 VladfromMosco 的回答对我来说似乎是正确的。
猜你喜欢
  • 2011-07-24
  • 2021-07-02
  • 2017-06-14
  • 2021-05-10
  • 2016-03-15
  • 2011-12-11
  • 1970-01-01
  • 2016-11-12
相关资源
最近更新 更多