2012-04-15 28 views
13

Sto riscontrando problemi nel creare un database basato su un elenco collegato singolarmente in C, , non a causa del concetto di elenco collegato, ma piuttosto dei campi stringa nella struttura stessa.Come lavorare con i campi stringa in una struct C?

Questo è un compito in C e per quanto ne so (sono un novizio), C non riconosce 'stringa' come tipo di dati.

Questo è ciò che il mio codice struct assomiglia:

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

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

stavo pensando di fare una struttura per le stringhe se stessi in modo che li posso utilizzare nella struct, in questo modo:

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

Quindi eseguirò uno o l'altroquando è necessario creare nuovi dati del tipo di stringa (matrice di caratteri).

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

Qualcuno può aiutarmi a capirlo?
Grazie.

risposta

0

Questo non funziona:

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

string si riferisce ad un puntatore, è necessario la dimensione della struttura stessa:

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

nota la mancanza del cast così (conversione da void* (Il tipo di ritorno di malloc viene eseguito implicitamente).

Inoltre, nel numero main, si dispone di uno patient delimitato a livello globale, ma non è inizializzato. Prova:

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

prima lettura l'accesso dei suoi membri

Inoltre, strcpy è intrinsecamente insicuro in quanto non ha il controllo di confine (copierà fino alla prima '\0' si incontra, scrivendo passato allocato memoria se la fonte è troppo lunga). Usa invece strncpy, dove puoi almeno specificare il numero massimo di caratteri copiati - leggi la documentazione per assicurarti di passare il valore corretto, è facile fare un errore "uno per uno".

+0

Si [non dovrebbe digitare] (http://stackoverflow.com/questions/605885/do-i-cast-the-result-of-malloc/605858#605858) mentre si utilizza malloc. –

+0

No. 'patient' non è dichiarato globalmente, è un typdef. Ma anche se fosse globale, non lo avresti inizializzato in questo modo. – kralyk

+0

@kralyk - corretto, me ne sono reso conto e corretto. – Attila

0

Si potrebbe utilizzare un ancora più semplice typedef:

typedef char *string; 

Poi, il malloc potrebbe apparire come un normale malloc:

string s = malloc(maxStringLength); 
31

sulle stringhe e allocazione di memoria:

Una stringa in C è solo una sequenza di char s, quindi è possibile utilizzare char * o un allineamento char ovunque si desidera utilizzare un tipo di dati stringa:

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

allora avete bisogno di allocare memoria per la struttura stessa, e per ciascuna delle stringhe:

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

Se avrete solo bisogno di qualche patient s, è possibile evitare la gestione della memoria, a scapito di allocare più memoria di quanto si ha realmente bisogno:

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; 

Negli elenchi concatenati:

In generale, lo scopo di un elenco collegato è quello di dimostrare l'accesso rapido a una raccolta di elementi ordinata. Se il tuo llist contiene un elemento chiamato num (che presumibilmente contiene il numero del paziente), hai bisogno di una struttura dati aggiuntiva per contenere gli stessi patient s, e dovrai cercare il numero del paziente ogni volta.

Invece, se si dichiara

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

quindi ogni elemento contiene un puntatore diretto a una struttura patient, ed è possibile accedere ai dati in questo modo:

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

ah quindi in pratica non ho bisogno di usare letteralmente il tipo di pungiglione e modificarlo nel puntatore se voglio usarlo come puntatore di char. grazie questo è davvero allettante. ma ho un paio di domande qui: (a) dire che voglio inserire un record per un nuovo paziente, devo fare una nuova fuction come void insert()? un po 'confuso con il struct patient per la typedef struct above (b) o devo inserire un nuovo (diciamo un nodo) che conterrà la struttura del paziente nella struttura list, inserendo diciamo, un nuovo nodo al elenco? è comprensibile .. grazie mille. – fleuracia

+0

Gli elenchi collegati sono una delle strutture dati fondamentali e di uso generale che ti saranno utili quando le capirai. Sarebbe un investimento utile per trovare una spiegazione più completa di quella che otterrai qui su SO. Un sacco di buoni siti web e libri sono disponibili. –

1

Mentre Richard è quello che volete se vuoi andare con un typedef, ti suggerirei che probabilmente non è un'idea particolarmente buona in questo caso, poiché perdi di vista il fatto che sia un puntatore, mentre non guadagni nulla.

Se lo si considera una stringa conteggiata, o qualcosa con funzionalità aggiuntive, che potrebbe essere diversa, ma mi raccomando davvero che in questa istanza, si acquisisca familiarità con l'implementazione della stringa C "standard" come " char * '...

Problemi correlati