【问题标题】:Cant print a string in a struct无法在结构中打印字符串
【发布时间】:2021-03-09 17:32:50
【问题描述】:

我正在尝试将字符串复制到结构中,但它不显示任何内容。你能帮我找出问题所在吗?

typedef struct{
    long tipo;
    char *buffer;
}msg;

msg mess;

strcpy(mess.buffer,"hello");
printf("%s\n",mess.buffer);

【问题讨论】:

  • char *buffer 是一个没有分配内存的指针。试试mess.buffer = "hello";(文本不可修改)或mess.buffer = strdup("hello");
  • 请注意,strdup 是非标准的(在 C23 标准之前)。如果它不可用,您可以使用strlenmallocstrcpy。在这两种情况下,当您不再需要为字符串分配的内存时,都应该使用free
  • @Bodo 我同意,但我认为 memcpy 会比 strcpy 更快,因为您不需要检查'\0',感谢strlen,您已经得到了它。我认为 OP 正在寻找一个 char 数组,他正在使用它的结构。
  • 请注意,结构无关紧要。您必须首先了解问题所在:char *buffer; strcpy(buffer, "hello");

标签: c string pointers


【解决方案1】:

观察strcpy declaration

char * strcpy ( char * destination, const char * source );

我们注意到它从源复制字符并将它们存储在目标中。但请注意,它没有指定目的地的长度。因此,如果目的地是:

  • 小于源(溢出)
  • 未分配给内存中的某些空间(分段错误)

这是因为 strcpy 函数试图逐个字符地复制字符,直到它到达“字符串”的末尾。看看它应该是什么样子:

char *strcpy(char *destination , const char *source ){
   char *saved = destination;
   while (*source){ // while is not NULL
       *destination++ = *source++;      // Pointer operation 
   }
   *destination = 0; // last position is set to 0 (which is NULL, end of string)
   return saved;
}

因此,当您执行strcpy(mess.buffer,"hello") 时,您实际上找不到mess.buffer++,因为您没有分配顺序内存,因此没有下一个内存块。因此,会发生分段错误。

最后,你可以这样做:

/* Note that "hello" occupies 6 char spaces: 'h', 'e', 'l', 'l', 'o', '\0' */
int mySize = 10; 
mess.buffer = malloc(mySize * sizeof(char));
strcpy(mess.buffer, "hello") // 10 > 6 so OK

【讨论】:

    【解决方案2】:

    要么直接分配字符串(注意你将不能再修改这个字符串):

    msg mess = {.buffer= "hello"};
    

    或使用 libc 中的 malloc 和 memcpy 函数,它们将执行内存分配并将字符串的字节复制到您的 char 指针:

    if (!(mess.buffptr = malloc(sizeof(char) * (strlen(s) + 1))))
        return 1;
    memcpy(mess.buffptr, s, strlen(s));
    

    但我认为您正在寻找的是使用 char buffer[128] 而不是 char 指针,请参见以下示例:

    #include <stdint.h>
    #include <string.h>
    #include <stdio.h>
    #include <stdlib.h>
    
    typedef struct{
      long tipo;
      char buffer[128];
      char *buffptr; // remove if not needed
    } msg;
    
    int main(){
      char *s = "hello";
      msg mess = {.buffer= "hello"};
      mess.buffer[1] = 'a';
      printf("'%s' assigned at struct initialization\n",mess.buffer);
      (void)mess.buffer;
      strcpy(mess.buffer,"hello");
      printf("'%s' char array strcpy\n",mess.buffer);
      int len = strlen(s) + 1; // to account for '\0'
      if (!(mess.buffptr = malloc(sizeof(char) * len)))
        return 1;
      if (len <= sizeof(mess.buffer))
        memcpy(mess.buffptr, s, len);
      printf("'%s' char ptr malloced\n",mess.buffptr);
    
      return 0;
    }
    

    您可以阅读更多关于 char 指针和 char 数组的区别here

    【讨论】:

    • 当您使用memcpy 复制字符串时,您必须使用strlen(s) + 1 复制'\0'。我建议将长度存储在一个变量中,并将其用于mallocstrcpy
    • 我必须承认我直到现在才检查大 thirtd 代码块。第二个代码块中仍然存在相同的错误。而不是if(len &lt;= 128),我建议if(len &lt;= sizeof(mess.buffer))。或者在这种情况下使用strncpy
    猜你喜欢
    • 2016-09-23
    • 2019-09-11
    • 2021-03-30
    • 2015-11-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多