Comment travailler avec string fields dans une structure c?

j'ai du mal à créer une base de données basée sur une liste en C, pas à cause du concept de liste liée, mais plutôt à cause des champs de chaîne dans la structure elle-même.

il s'agit d'une tâche en C et pour autant que je sache (je suis un débutant), C ne reconnaît pas 'string' comme un type de données.

voici à quoi ressemble mon code struct:

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

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

je pensais faire une structure pour les chaînes elles-mêmes, afin que je puisse les utiliser dans la structure, comme ceci:

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

Alors je suis d' malloc() chacun d'eux quand il est nécessaire de faire de nouvelles données de type chaîne de caractères (tableau de 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);
}

quelqu'un Peut-il m'aider à comprendre cela?

Remercier.

15
demandé sur Adam Liss 2012-04-15 16:50:14

4 réponses

chaînes de caractères, et l'allocation de mémoire:

une chaîne en C est juste une séquence de chars, de sorte que vous pouvez utiliser char * et char array partout où vous souhaitez utiliser un type de données string:

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

Ensuite, vous devez allouer de la mémoire pour la structure elle-même, et pour chacune des chaînes:

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

Si vous aurez seulement besoin d'un peu patients, vous pouvez éviter la gestion de la mémoire au détriment d'allouer plus de mémoire que vous avez vraiment besoin de:

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;

Sur les listes chaînées:

En général, le but d'une liste chaînée est de prouver un accès rapide à une collection ordonnée d'éléments. Si votre llist contient un élément appelé num (qui contient probablement le numéro du patient), vous avez besoin d'une structure de données supplémentaires pour tenir le patients eux-mêmes, et vous aurez besoin de chercher le numéro du patient à chaque fois.

à la place, si vous déclarez

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

alors chaque élément contient un pointeur direct vers un patient structure, et vous pouvez accéder aux données comme ceci:

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;
}
35
répondu Adam Liss 2013-03-20 01:39:12

alors que Richard est ce que vous voulez si vous voulez aller avec un typedef, je dirais que ce n'est probablement pas une bonne idée dans ce cas, comme vous perdez de vue qu'il est un pointeur, tout en ne gagnant rien.

si vous le traitiez comme une chaîne comptée, ou quelque chose avec des fonctionnalités supplémentaires, cela pourrait être différent, mais je recommande vraiment que dans ce cas, vous vous familiarisiez avec l'implémentation de la chaîne C' standard 'étant un' char *'...

1
répondu Gwyn Evans 2012-04-15 13:07:54

Vous pouvez simplement utiliser un moyen encore plus simple typedef:

typedef char *string;

alors, votre malloc ressemblerait à un malloc habituel:

string s = malloc(maxStringLength);
0
répondu Richard J. Ross III 2012-04-15 12:58:09

Cela ne fonctionne pas:

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

string renvoie un pointeur, vous avez besoin de la taille de la structure elle-même:

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

Notez aussi le manque de casting (conversion de void* (malloc'type de retour) est implicitement réalisée).

Aussi, dans votre main, vous avez l'échelle mondiale benoit xvi a déclaré patient, mais cela n'est pas initialisé. À essayer:

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

avant de lire-accédez à l'un de ses membres

Également strcpy est intrinsèquement dangereuses comme il n'y a pas de vérification des limites (copie jusqu'à la première '' est rencontré, en écrivant au-delà de la mémoire allouée si la source est trop longue). Utilisez strncpy au lieu de cela, où vous pouvez au moins spécifier le nombre maximum de caractères copiés -- lisez la documentation pour vous assurer de passer la bonne valeur, il est facile de faire une erreur "off-by-one".

0
répondu Attila 2012-04-15 13:00:38