我在基于 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()
它们中的每一个。
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);
}
有人可以帮我解决这个问题吗?
谢谢。
关于字符串和内存分配:
C 中的字符串只是 char
s 的序列,因此您可以在任何想要使用字符串数据类型的地方使用 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;
}
如果您只需要几patient
,则可以避免内存管理,但代价是分配的内存比实际需要的内存多:
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
本身,并且每次都需要查找患者编号。
相反,如果您声明
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;
}
我认为这个解决方案使用的代码更少,即使对于新手也很容易理解。
对于结构中的字符串字段,您可以使用指针,将字符串重新分配给该指针将更加简单明了。
定义结构的定义:
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';
就是这么简单。希望这个答案对许多开发人员有所帮助。
虽然 Richard's 是你想要的,如果你确实想使用 typedef,但我建议在这种情况下它可能不是一个特别好的主意,因为你忽略了它是一个指针,同时没有获得任何东西。
如果您将其视为计数字符串或具有附加功能的东西,那可能会有所不同,但我真的建议您在这种情况下,您只需熟悉"标准"C 字符串实现是"char *"...
您可以使用更简单的typedef
:
typedef char *string;
然后,您的malloc看起来像一个普通的malloc:
string s = malloc(maxStringLength);
不起作用:
string s = (string)malloc(sizeof string);
string
引用指针,则需要结构本身的大小:
string s = malloc(sizeof (*string));
注意缺少强制转换(从void*
转换(malloc
的返回类型)是隐式执行的)。
另外,在你的main
中,你有一个全局的patient
,但它是未初始化的。 尝试:
patient.number = 3;
patient.name = "John";
patient.address = "Baker street";
patient.birthdate = "4/15/2012";
patient.gender = 'M';
在读取访问其任何成员之前
此外, strcpy
本质上是不安全的,因为它没有边界检查(将复制直到遇到第一个' '
,如果源太长,将写入分配的内存)。 请改用strncpy
,您至少可以指定复制的最大字符数 - 阅读文档以确保传递正确的值,很容易出现逐一错误。