2012-04-15 72 views
13

我在制作基于C, 中单链表的数据库时遇到了困难,这不是因为链表概念,而是因为结构本身中的字符串字段。如何使用C结构中的字符串字段?

这是C中的一个赋值,据我所知(我是一个新手),C不会将'string'识别为数据类型。

这是我的结构代码如下所示:

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); 
} 

有人可以帮我弄清楚这一点吗?
谢谢。

回答

0

这不起作用:

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的是固有的不安全,因为它没有边界检查(将复制到第一'\0'遇到,写拨了过去记忆如果来源太长)。改为使用strncpy,您至少可以指定复制的最大字符数 - 请阅读文档以确保您传递正确的值,否则很容易造成错误。

+0

你[不应该使用类型](http://stackoverflow.com/questions/605845/do-i-cast-the-result-of-malloc/605858#605858),而使用malloc。 – 2012-04-15 12:56:35

+0

编号'patient'没有全局声明,这是一个typdef。但即使它是全球性的,你也不会像这样初始化它。 – kralyk 2012-04-15 13:04:17

+0

@ kralyk - 正确的,我自己意识到并纠正了。 – Attila 2012-04-15 13:05:14

0

你可以只使用一个更简单的typedef

typedef char *string; 

然后,你的malloc看起来像一个平常的malloc:

string s = malloc(maxStringLength); 
31

对字符串和内存分配:

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 S,你可以分配更多的内存为代价避免了内存管理比你真正需要的:

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; 
} 
+0

啊所以基本上我不需要从字面上使用sting类型并将其修改为指针,如果我想用它作为char指针。谢谢你,这真是令人眼前一亮。但我在这里遇到了一些问题:(a)说我想插入一个新病人的记录,我是否必须做出像void insert()这样的新功能?与(b)中的typedef结构的结构病人有点混淆,或者我必须插入一个新的(比如说一个节点),它将在列表结构中包含病人结构,插入一个新节点到清单?这是可以理解的..非常感谢。 – fleuracia 2012-04-15 15:45:41

+0

链接列表是基本的通用数据结构之一,一旦你理解了它们,它们将很好地为你服务。找到一个比你在这里讨论的更全面的解释是值得的投资。有很多优秀的网站和书籍可供选择。 – 2012-04-15 20:04:15

1

虽然理查德的是你想要的如果你确实想要使用typedef,我会建议在这种情况下这可能不是一个特别好的主意,因为你没有看到它是一个指针,而没有获得任何东西。

如果你把它看作是一个计数的字符串,或者是带有附加功能的东西,可能会有所不同,但我真的建议在这种情况下,你只需要熟悉'标准'C字符串实现是' char *'...

相关问题