2012-04-15 3 views
13

의 단일 링크 된 목록을 기반으로 데이터베이스를 만드는 데 문제가 있습니다. 링크 된 목록 개념이 아니라 struct 자체의 문자열 필드 때문입니다.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; 

그러면 문자열 유형 (char의 배열)의 새 데이터를 만들어야 할 때마다 각각 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); 
} 

다른 사람이 알아낼 수 있습니까?
감사합니다.

답변

0

이 작동하지 않습니다 : (

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

참고뿐만 아니라 주조의 부족 void*에서 (변환 :

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

string

이 포인터를 참조, 당신은 구조 자체의 크기를 필요 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

malloc을 사용하는 동안 당신은 [형식 변환을해서는 안됩니다.] (http://stackoverflow.com/questions/605845/do-i-cast-the-result-of-malloc/605858#605858). –

+0

아니요. '환자'가 전역 적으로 선언되지 않았습니다. 이는 typdef입니다. 그러나 그것이 글로벌 일지라도, 여러분은 이것을 초기화하지 않을 것입니다. – kralyk

+0

@kralyk - 정확합니다. 직접 깨닫고 수정했습니다. – Attila

0

당신은 사용할 수있는 더 간단한 typedef :

typedef char *string; 

그런 다음, 당신의 malloc는 보통의 malloc과 같을 것이다

:

string s = malloc(maxStringLength); 
문자열과 메모리 할당에
31

:

C의 문자열은 char의 시퀀스이므로 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; 

연결된 목록에 :

일반적으로 연결된 목록의 목적은 정렬 된 요소 컬렉션에 빠르게 액세스하는 것입니다. llistnum (환자 번호가 포함되어있을 수 있음) 요소가 포함되어있는 경우 실제 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

아 기본적으로 글자 그대로 찌르기 유형을 사용하고 char의 포인터로 사용하려면 포인터로 수정하지 않아도됩니다. 정말 고맙습니다. 하지만 난 여기에 몇 가지 질문이있어 : (a) 내가 새로운 환자에 대한 레코드를 삽입하려면, 내가 void fert() 같은 새로운 fuction 만들어야할까요? 위의 typedef 구조체의 구조체 환자와 혼동을 일으키거나 (b) 또는 목록 구조에 환자 구조체가 포함될 새 노드를 삽입해야합니까? 명부? 이게 이해할 수 있니? 고마워. – fleuracia

+0

링크 된 목록은 일단 이해하면 잘 전달할 수있는 기본 범용 데이터 구조 중 하나입니다. SO에 대해보다 포괄적 인 설명을 찾는 것이 가치있는 투자 일 것입니다. 좋은 웹 사이트와 책들이 많이 있습니다. –

1

을 리처드의 당신이 원하는 동안 당신이 typedef로 가고 싶다면, 나는이 인스턴스에서 포인터를 보지 못하고 아무것도 얻지 못하는 것을 보면서이 인스턴스에서 특히 좋은 생각은 아닐 것이라고 제안합니다.

만약 당신이 그것을 다룰 줄 아는 문자열이나 다른 기능을 가진 뭔가가 다를 지 모르지만 나는이 예제에서 '표준'C 문자열 구현에 익숙해지기를 ' char * '...

관련 문제