26

我在基于 C 中的单链表创建数据库时遇到问题,不是因为链表概念,而是因为结构本身中的字符串字段。

这是 C 中的一项任务,据我所知(我是新手),C 不将“字符串”识别为数据类型。

这是我的结构代码的样子:

typedef struct 
{
  int number;
  string name;
  string address;
  string birthdate;
  char gender;
} patient;

typedef struct llist
{
  patient num;
  struct llist *next;
} list;

我正在考虑为字符串本身制作一个结构,以便我可以在结构中使用它们,如下所示:

typedef struct string 
{ 
  char *text;
} *string;

malloc()然后,当需要创建字符串类型(char 数组)的新数据时,我将它们中的每一个。

typedef struct string
{
  char *text;
} *string;

int main()
{
    int length = 50;
    string s = (string) malloc(sizeof string);
    s->text = (char *) malloc(len * sizeof char);
    strcpy(s->text, patient.name->text);
}

有人可以帮我解决这个问题吗?
谢谢你。

4

5 回答 5

58

关于字符串和内存分配:

C 中的字符串只是chars 的序列,因此您可以在任何您想使用字符串数据类型的地方使用char *或数组:char

typedef struct     {
  int number;
  char *name;
  char *address;
  char *birthdate;
  char gender;
} patient;

然后你需要为结构本身和每个字符串分配内存:

patient *createPatient(int number, char *name, 
  char *addr, char *bd, char sex) {

  // Allocate memory for the pointers themselves and other elements
  // in the struct.
  patient *p = malloc(sizeof(struct patient));

  p->number = number; // Scalars (int, char, etc) can simply be copied

  // Must allocate memory for contents of pointers.  Here, strdup()
  // creates a new copy of name.  Another option:
  // p->name = malloc(strlen(name)+1);
  // strcpy(p->name, name);
  p->name = strdup(name);
  p->address = strdup(addr);
  p->birthdate = strdup(bd);
  p->gender = sex;
  return p;
}

如果您只需要几个patients,则可以避免内存管理,但会分配比实际需要更多的内存:

typedef struct     {
  int number;
  char name[50];       // Declaring an array will allocate the specified
  char address[200];   // amount of memory when the struct is created,
  char birthdate[50];  // but pre-determines the max length and may
  char gender;         // allocate more than you need.
} patient;

在链表上:

一般来说,链表的目的是证明对有序元素集合的快速访问。如果您llist包含一个名为的元素num(可能包含患者编号),您需要一个额外的数据结构来保存实际patient的 s 本身,并且您每次都需要查找患者编号。

相反,如果您声明

typedef struct llist
{
  patient *p;
  struct llist *next;
} list;

然后每个元素都包含一个指向patient结构的直接指针,您可以像这样访问数据:

patient *getPatient(list *patients, int num) {
  list *l = patients;
  while (l != NULL) {
    if (l->p->num == num) {
      return l->p;
    }
    l = l->next;
  }
  return NULL;
}
于 2012-04-15T13:02:50.050 回答
4

我认为这个解决方案使用的代码更少,即使对于新手来说也很容易理解。

对于结构中的字符串字段,您可以使用指针并将字符串重新分配给该指针将变得简单明了。

定义结构的定义:

typedef struct {
  int number;
  char *name;
  char *address;
  char *birthdate;
  char gender;
} Patient;

使用该结构的类型初始化变量:

Patient patient;
patient.number = 12345;
patient.address = "123/123 some road Rd.";
patient.birthdate = "2020/12/12";
patient.gender = 'M';

就是这么简单。希望这个答案可以帮助许多开发人员。

于 2020-10-21T01:21:05.237 回答
1

如果您确实想使用 typedef,虽然 Richard's 是您想要的,但我建议在这种情况下这可能不是一个特别好的主意,因为您忽略了它是一个指针,而没有获得任何东西。

如果您将其视为计数字符串或具有附加功能的东西,那可能会有所不同,但我真的建议在这种情况下,您只需熟悉“标准”C 字符串实现是“char *”即可。 ..

于 2012-04-15T13:07:54.103 回答
0

这不起作用:

string s = (string)malloc(sizeof string); 

string指的是指针,你需要结构体本身的大小:

string s = malloc(sizeof (*string)); 

请注意也缺少强制转换(隐式执行从void*(malloc的返回类型的转换)。

此外,在您的 中main,您有一个全局的 delcared patient,但它是未初始化的。尝试:

 patient.number = 3;     
 patient.name = "John";     
 patient.address = "Baker street";     
 patient.birthdate = "4/15/2012";     
 patient.gender = 'M';     

在您读取其任何成员之前

此外,strcpy本质上是不安全的,因为它没有边界检查(将复制直到'\0'遇到第一个,如果源太长则写入过去分配的内存)。改为使用strncpy,您至少可以指定复制的最大字符数 - 阅读文档以确保您传递正确的值,很容易出错。

于 2012-04-15T12:53:38.177 回答
0

您可以使用更简单的typedef

typedef char *string;

然后,你的 malloc 看起来就像一个普通的 malloc:

string s = malloc(maxStringLength);
于 2012-04-15T12:58:09.130 回答