【问题标题】:Storing string inside a C struct将字符串存储在 C 结构中
【发布时间】:2019-09-23 03:16:47
【问题描述】:

作为计算机科学作业,我被要求制作一个使用下面这段代码的算法。问题是,Name 结构中的字符串被存储为指针,所以当我得到下一个输入时,所有字符串都是相同的,这会破坏我完整代码的功能。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define DEFAULT_CAP 5
#define SUCCESS 1
#define FAILURE 0
#define MAX_LINES 100000

typedef struct Name
{
  char *string;
} Name;

Name *initializeName(char *inputedName)
{
  Name *name = calloc(1, sizeof(Name));
  if (name != NULL)
  {
    name->string = inputedName;
  }
  return name;
}

void printName(Name *name){
  printf("Name -> %s\n", name->string);
}

int main() {

    Name **name;

    for(int i=0; i< 3; i++) {
        char string[100];
        scanf("%s", string);
        name[i] = initializeName(string);
        for(int j = 0; j<=i;j++) {
            printName(name[i]);
        }
    }


    return 0;
}

这是一个测试代码,其中提到了损坏的功能。它扫描字符串并将其存储在名称中,并将名称放入名称数组中。

如何让 Name->string 存储为字符串?

【问题讨论】:

  • 不要只复制指针(name-&gt;string = inputedName);分配新的存储空间并复制字符串内容。
  • @n.m.我无法用引用的问题解决问题。尽管它们表面上可能相关,但我相信它们会处理不同的情况。

标签: c string memory-management struct


【解决方案1】:

分配struct Name 后,您可以继续分配空间来存储字符串本身的副本:

if (name != NULL)
{
    /* +1 for null terminator at end of string */
    size_t string_length = strlen(inputedName) + 1;

    name->string = calloc(string_length, 1);

如果成功,则可以将字符串复制到新分配的空间中(如果失败,则需要释放分配的struct Name):

    if (name->string != NULL)
    {
        memcpy(name->string, inputedName, string_length);
    }
    else
    {
        free(name);
        name = NULL;
    }

main() 中也有错误。 Name **name; 是一个指针,但它还没有指向任何地方,所以你不能访问name[i]。您的for() 循环只能从name[0] 访问到name[2],因此将定义更改为三个Name * 指针的数组将解决它:

Name *name[3];

【讨论】:

  • 即使在进行了这些更改之后,Name 数组中的字符串也是一样的。它是这样发生的:string1 输出 Name -&gt; string1 | string 2 输出 Name -&gt; string2\nName -&gt; string2
  • @victormoraesgs:在此更改之后,每个Name 中的字符串都不同,但您的循环始终打印相同的字符串,因为它循环了j,但打印了name[i]
【解决方案2】:
name->string = inputedName;

不复制字符串。你要strdup

name->string = strdup(imputedName);

【讨论】:

  • @bigdataolddriver:不是。他已经有一个calloc 上面两行了。
  • @bigdataolddriver 是正确的 - 他所指的错误在 main 中,其中声明了 Name **name;,然后在没有内存分配的情况下访问 name[i]
  • 哦,是的,我在接受@joshua 对calloc 的解释后有一种奇怪的感觉。我一次又一次地上下打量,直到@caf 指出
  • 即使在初始化数组并使用 strdup 之后,字符串仍然是相同的
  • @victormoraesgs:正如 caf 已经指出的那样,你在这里有一个错字printName(name[i]); shold read printName(name[j]);
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-08-26
  • 2015-07-27
  • 1970-01-01
  • 1970-01-01
  • 2011-07-13
  • 2015-04-25
相关资源
最近更新 更多