简体   繁体   English

C-创建字符串“ from”结构参数

[英]C - create a string “from” struct parameter

Have a 有一个

typedef struct person {
    char name[20]
    char surname[20]
} person_t;

I need to create a string like XXXXXX:YYYYYY with the function like char* personToString(person_t *p) . 我需要使用像char* personToString(person_t *p)这样的函数来创建一个像XXXXXX:YYYYYY这样的字符串。 I tried to make it: 我试图做到:

char* personToString(person_t* p) {

  int n1,n2;
  n1=strlen(p->name);
  n2=strlen(p->surname);
  char *p = (char*) malloc((n1+n2+2)*sizeof(char));
  strcat(p,puser->name);
  strcat(p,":");
  strcat(p,puser->surname);

  return p;
}

This give me a reasonable output but I have some errors testing with valgrind! 这给了我一个合理的输出,但是我用valgrind测试了一些错误! I also think that there is a way more classy to write the function! 我也认为有一种更优雅的方式来编写函数!

When you malloc memory for p the memory will hold garbage values. 当您为p分配内存时,内存将保存垃圾值。 Strcat will append a string after the null character, but in an uninitialized string will hold random values. Strcat将在空字符后附加一个字符串,但在未初始化的字符串中将保留随机值。

Replace the first strcat with strcpy. 将第一个strcat替换为strcpy。

You need to 你需要

strcpy(p,puser->name);

not

strcat(p,puser->name);

malloc does not initialize the buffer to zero, so strcat is searching for a null byte in p first and probably not finding one, reading past the end of the buffer and thus crashing. malloc不会将缓冲区初始化为零,因此strcat首先在p中搜索一个空字节,可能找不到一个,读取到缓冲区末尾并因此崩溃。

Instead of one strcpy plus two strcat you can also write one call to sprintf: 除了一个strcpy加两个strcat之外,您还可以编写一个sprintf调用:

sprintf(p, "%s:%s", puser->name, puser->surname);

First you should call string copy, then strcat: 首先,您应该调用字符串复制,然后调用strcat:

strcat(p,puser->name);

should be: 应该:

strcpy(p,puser->name);

because memory allocated with malloc function keeps values garbage, by doing strcat for first you are concatenating after garbage -- it also brings Undefined behaviour in your code. 因为使用malloc函数分配的内存使值保持垃圾状态,所以首先执行strcat就是在垃圾级联之后进行连接-这还会在代码中带来未定义的行为。

You can use void* calloc (size_t num, size_t size); 您可以使用void* calloc (size_t num, size_t size); instead of malloc(), calloc function initialized allocated memory with 0 (then strcat() no problem). 而不是malloc(),calloc函数将分配的内存初始化为0 (然后strcat()没问题)。 Also dynamically allocated memory you should deallocate memory block using void free (void* ptr);) explicitly. 同样,动态分配的内存也应该使用void free (void* ptr);)显式地释放内存块。

This looks good to me, 这对我来说很好

char* personToString( struct person_t *p )
{
  int len = strlen(p->name) + strlen(p->surname) + 2; // holds ':' + NULL 
  char *str = malloc( len ); // Never cast malloc's return value in C

  // Check str for NULL
  if( str == NULL )
  {
      // we are out of memory
      // handle errors
      return NULL;
  }

  snprintf( str, len, "%s:%s", p->name, p->surname);

  return str;
}

NOTE: 注意:

  1. Never cast malloc 's return value in C. 切勿在C中malloc的返回值。
  2. Use snprintf when multiple strcat is needed, its elegant. 当需要多个strcat时,请使用snprintf ,这很优雅。
  3. free the return value str here in caller. 在调用str free返回值str

Fixed struct and char variables . 固定的structchar变量

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM