Forum Programmation.c string.h et pointeurs...

Posté par  .
Étiquettes : aucune
0
29
oct.
2005
Hello!

je commence le C et j'ai des soucis avec les chaines de caractères...
Normal me direz vou mais ca fait un moment que je bloque...
:/
Je voudrais découper le contenu d'une saisie suivant les espaces.
Cela marche bien avec strtok, mais si je veux utiliser strstr ou strcpy j'ai systématiquement des plantages.

char *strncpy(char *dest, const char *srce, size_t maxlen);
char *strstr(const char *s1, const char *s2);

1) Comment puis-je rendre mes données homogènes avec les *const char?

2)Peut-être malloc mais je n'ai pas trop compris pourquoi l'utiliser.
mes données sans malloc ne sont pas stockées dans la mémoire?


#include <stdio.h>;
#include <string.h>;
char saisie[80]
void commande(int *num_argument, char *argument[])
{
char *temp,*saisie_espace;

fgets(saisie, sizeof saisie, stdin);
argument[*num_argument]=strtok(saisie," ");
strcpy(temp,argument[num_argument]);
saisie_espace=strstr(temp," ");

...
}

int main()
{
char *argument[10];
int num_argument=0;
...
}

[/C]
  • # Re : string.h et pointeurs...

    Posté par  . Évalué à 0.

    pour le 1, si tes variables sont de type char*, ca suffit, le const dans le prototype de la fonction indique juste au compilateur de verifier qu'on ne modifie pas le contenu

    pour 2, la memoire est repartie en 3 bloc, le tas (malloc, allocation des variables losr de l'appel de fonction, ...), la pile utilisee pour allouer la memoire pour le passage des parametres des fonctions, et un 3eme truc (j'ai pas de memoire pour le nom :/ ) qui est utilise pour les variables globales ou du main

    donc saisie est dans ce 3eme espace, et prend 80*sizeof(char) octets, si tu declare saisie comme : char *saisie, la variable ne prend que sizeof(char*) octets, mais apres tu dois faire saisie=(char*)malloc(80*sizeof(char)) pour allouer de l'espace, a ce moment la, la memoire n'est plus prise dans le 3eme espace, mais dans le tas...

    enfin, pour strtok, la fonction remplace tous les delimiteurs (ici seulement ' ') pas un \0 (fin de chaine), il faut faire une boucle sur avec un strtok pour recuperer tous les elements separes un par un
    • [^] # Re: Re : string.h et pointeurs...

      Posté par  . Évalué à 1.

      tu dois faire saisie=(char*)malloc(80*sizeof(char))
      Non:
      saisie = malloc(80)

      Car:
      1) sizeof(char) fait 1 par définition dans la norme du C.
      2) caster le retour de malloc en C non seulement inutile (un void * est casté automatiquement en T*), mais aussi dangereux (ça peut cacher une inclusion d'en-tête manquante).

      cf. http://mapage.noos.fr/emdel/
  • # Pointeurs...

    Posté par  . Évalué à 4.

    Je pense que tu n'as pas tout à fait compris les liens entre chaînes de caractères, pointeurs, et mémoire physique.

    En C, les chaînes de caractères sont définies en mémoire comme une suite de caractères contigus terminée par le caractère NUL, '\0'.

    Par exemple, en imaginant la mémoire physique comme un tableau:
    [ 'H' | 'e' | 'l' | 'l' | 'o' | '\0' ]

    Maintenant, comment représente-t-on, ou accède-t-on à un espace mémoire en C ?

    * Un pointeur contient l'adresse d'une zone mémoire quelconque. On peut donc l'associer avec n'importe quel espace mémoire (à ses risques et périls).
    * Le tableau définit entièrement un espace mémoire; il pointe implicitement vers l'emplacement mémoire de son premier élément.

    donc :
    char *pointeur = NULL; n'est pas une chaine de caractère, il n'a pas de mémoire associée
    char tableau[6] = { 'H', 'e', 'l', 'l', 'o' }; est une chaine de caractère; le nom 'tableau' renvoie directement à la mémoire contenant "Hello";

    Pour avoir une 'chaîne de caractère' avec un pointeur, il faut donc lui associer de la mémoire.

    pointeur = tableau;

    On associe l'espace mémoire contenant la chaîne "Hello" du tableau à notre pointeur. Attention, le pointeur et le tableau référencent par conséquent la même mémoire 'physique'. Donc changer la chaîne avec pointeur[0] = 'h'; par exemple modifiera le tableau aussi ;)

    A noter: dès qu'un pointeur est associé à un espace mémoire, on peut le manipuler comme un tableau. On peut aussi jouer sur l'adresse enregistrée pour se "déplacer" dans la zone. Par exemple, pointeur ++ positionnera le pointeur sur le 'e' de "Hello".

    On peut aussi demander un nouvel espace mémoire au système en utilisant malloc, qui renvoie un pointeur.

    Pour copier "Hello", on peut donc faire:
    pointeur = malloc( (strlen(tableau) + 1) * sizeof(*pointeur));
                                   ^ taille de la chaine    ^ taille du type de tableau

    Attention au '+1', il ne faut pas oublier le zero final !
    A ce stade, on a une nouvelle zone mémoire vierge de la même taille que "Hello". On va donc copier le tableau dans la nouvelle zone mémoire.

    strncpy(pointeur, tableau, sizeof(tableau));

    Voilà, on dispose d'une copie de la chaîne "Hello".

    Si je n'ai pas été trop confus dans mes explications, tu devrais donc voir que ton programme plante, car tu utilises le pointeur temp sans lui avoir associé un espace mémoire.

    Dans ce cas, strncpy() écrit n'importe où, et strstr() lit on ne sait où...

    Ce désordre met Linux en colère, qui abat alors froidement ton programme d'un SIGSEGV dans la nuque, ce qui se résume souvent par un pauvre "Segmentation fault" dans ton terminal.
    • [^] # Re: Pointeurs...

      Posté par  . Évalué à 1.

      Merci pour cette réponse complète! ;) Exactement ce que je voulais savoir.
      J'essaye d'appliquer tout ca et je met à jour!
      Bon week end!

Suivre le flux des commentaires

Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.