【问题标题】:Assign string to element in structure in C将字符串分配给C中结构中的元素
【发布时间】:2012-08-29 14:07:15
【问题描述】:

我有这个结构:

typedef struct SM_DB
{
    LIST_TYPE           link;
    char                name[SM_NAME_SIZE];
} SM_DB_TYPE;

我想为其“名称”分配一个字符串。我这样做是这样的:

SM_DB_TYPE one;
one.name = "Alpha";

但是,编译后出现错误:“错误 C2106:'=':左操作数必须是左值”。我希望这是相当明显的。有谁知道我做错了什么?

谢谢

【问题讨论】:

  • 您不能将字符串分配给 char 数组。
  • 可以,但必须同时进行,即char name[SM_NAME_SIZE] = "Alpha";

标签: c string structure


【解决方案1】:

假设SM_NAME_SIZE 足够大,您可以像这样使用strcpy

strcpy(one.name, "Alpha");

在执行 strcpy 之前确保您的目的地有足够的空间来保存字符串,您将获得缓冲区溢出。

如果你想安全起见,你可以这样做

if(!(one.name = malloc(strlen("Alpha") + 1))) //+1 is to make room for the NULL char that terminates C strings
{
      //allocation failed
}
strcpy(one.name, "Alpha");  //note that '\0' is not included with Alpha, it is handled by strcpy
//do whatever with one.name
free(one.name) //release space previously allocated

如果使用 malloc,请确保释放 one.name,以免浪费内存。

【讨论】:

  • 据我所知,我们不能为数组分配内存。不是吗?但你的回答仍然给我指明了一条路。
【解决方案2】:

您只能在声明字符串时为其赋值。您以后不能使用= 分配它。

你必须使用strcpy()函数。

【讨论】:

    【解决方案3】:

    使用strcpystrncpy 在C 中分配字符串。

    【讨论】:

    • 或者如果你可以使用它们,strcpy_s 或 strncpy_s。
    • 或者,如果你知道源字符串的长度,使用memmove()memcpy()——如果你不知道源字符串的长度,你怎么知道它是安全的将字符串复制到目标中。
    【解决方案4】:

    C 没有内置的字符串类型。您必须使用字符数组来保存字符串。

    由于 C 也不允许将一个数组分配给另一个数组,因此您必须使用标准 C 库中的各种函数将数组元素从一个数组复制到另一个数组,或者您必须自己编写一个循环来完成。尽管有时有理由编写自己的循环,但使用标准 C 库函数更为可取。

    对于与 char 类型一起使用的标准 ANSI 类型字符串,有大量函数,其中大多数以 str 开头,例如用于复制或比较字符串 strcpy()strcmp() 的函数。还有另一组,您可以指定要复制或比较的最大字符数,例如 strncpy()strncmp()

    C 中的字符串是一个以二进制零字符结尾的字符数组。因此,如果您使用诸如“Constant”之类的常量字符串,这将创建一个字符数组,其中每个字符一个元素加上一个用于零终止符的附加元素。

    这意味着在调整 char 数组大小时,您还必须记住再添加一个额外的数组元素来保存零终止符。

    strncpy() 函数会将一个 char 数组复制到另一个,直到指定的最大字符数或找到零终止符时。如果达到最大字符数,则目标数组将不会被零终止符终止,因此需要注意这一点。

    char  one[10];
    char  two[20];
    strncpy (one, "1234567", 10);  // copy constant to the char buffer max of 10 chars
    one[9] = 0;   // make sure the string is zero terminated, it will be this is demo
    strcpy (two, one);
    strcat (two, " suffix");    // add some more text to the end
    

    还有一些函数可以处理与 UNICODE 一起使用的宽字符。

    【讨论】:

      【解决方案5】:

      用途:

      strcpy(one.name, "Alpha"); //Removed null byte (Read first comment by shf301)
      

      替代方案:

      typedef struct SM_DB  
      {
          LIST_TYPE           link;
          char*               name;   
      } SM_DB_TYPE;
      
      SM_DB_TYPE one;
      one.name = malloc(sizeof(char) * (strlen("Alpha") + 1); //Allocate memory
      if (!one.name) {
         /* Error handling */
      } else {
          strcpy(one.name, "Alpha");
      }
      

      【讨论】:

      • 您不需要 '\0' in。字符串常量在末尾隐含一个空零。 "Alpha\0" 创建一个带有两个尾随空零的字符串。
      • 你不觉得sizeof(char) 有点多余,因为char 只有一个字节吗?除非我想错了这不是说malloc(1 * strlen("Alpha\0"))吗?
      • @KeithMiller 只是增加了可读性(特别是考虑到读者可以根据他们的专业知识有很大差异)
      • 当你删除\0 时,strlen 值对于 malloc 来说太短了一个字节...
      • @BoPersson 我犯了非常愚蠢的错误。感谢您的跟进。 :)
      猜你喜欢
      • 2017-06-12
      • 2021-04-29
      • 1970-01-01
      • 2013-12-26
      • 1970-01-01
      • 2015-04-07
      • 1970-01-01
      • 1970-01-01
      • 2015-09-25
      相关资源
      最近更新 更多