Structure / Chaines / printf erroné

Structure / Chaines / printf erroné - C - Programmation

Marsh Posté le 16-05-2010 à 17:20:25    

Bonjour.
 
Je recherche une explication au comportement d'un code.
 

Code :
  1. #include <stdio.h>
  2. #include <string.h>
  3. #include <unistd.h>
  4. struct data {
  5.    char var1[6];
  6.    char var2[2];
  7.    char var3[12];
  8.    char var4[8];
  9. };
  10. void fct(char *buf, int size) {
  11.    int x=0;
  12.    while (x<size) {buf[x] = x+65; x++;}
  13.    buf[size] = '\0';
  14. }
  15. void snd(struct data* dt) {
  16.    fct(dt->var1,sizeof(dt->var1));
  17.    printf("Strncpy struct var1 = %s = %d\n",dt->var1,sizeof(dt->var1));
  18.  
  19.    fct(dt->var2,sizeof(dt->var2));
  20.    printf("Strncpy struct var2 = %s = %d\n",dt->var2,sizeof(dt->var2));
  21.  
  22.    fct(dt->var3,sizeof(dt->var3));
  23.    printf("Strncpy struct var3 = %s = %d\n",dt->var3,sizeof(dt->var3));
  24.  
  25.    fct(dt->var4,sizeof(dt->var4));
  26.    printf("Strncpy struct var4 = %s = %d\n",dt->var4,sizeof(dt->var4));
  27.  
  28.    printf("var1 = %s\nvar2 = %s\nvar3 = %s\nvar4 = %s\n",dt->var1,dt->var2,dt->var3,dt->var4);
  29. }
  30. int main() {
  31.    struct data mydata;
  32.    while (1) {
  33.       snd(&mydata);
  34.       printf("\n" );
  35.       sleep(1);
  36.    }
  37.  
  38.    return 0;
  39. }


 
L'affichage de mes variables est :

Code :
  1. Strncpy struct var1 = ABCDEF = 6
  2. Strncpy struct var2 = AB = 2
  3. Strncpy struct var3 = ABCDEFGHIJKL = 12
  4. Strncpy struct var4 = ABCDEFGH = 8
  5. var1 = ABCDEFABABCDEFGHIJKLABCDEFGH
  6. var2 = ABABCDEFGHIJKLABCDEFGH
  7. var3 = ABCDEFGHIJKLABCDEFGH
  8. var4 = ABCDEFGH


 
Je ne comprends pas pourquoi lors du dernier printf, mes données sont erronées et se "superposent".
Si quelqu'un pouvait me dire l'erreur que je fais. Merci.

Reply

Marsh Posté le 16-05-2010 à 17:20:25   

Reply

Marsh Posté le 16-05-2010 à 19:03:05    

J'ai remarqué qu'en laissant un espace libre à la fin de chaque chaine, l'erreur disparait.
Pré-requis ou hasard ?

 
Code :
  1. #include <unistd.h>
  2. struct data {
  3.    char var1[6];
  4.    char var2[2];
  5.    char var3[12];
  6.    char var4[8];
  7. };
  8. void fct(char *buf, int size) {
  9.    int x=0;
  10.    while (x<size-1) {buf[x] = x+65; x++;}
  11.    buf[size-1] = '\0';
  12. }
  13. void snd(struct data* dt) {
  14.    fct(dt->var1,sizeof(dt->var1));
  15.    printf("Strncpy struct var1 = %s = %d\n",dt->var1,sizeof(dt->var1));
  16.  
  17.    fct(dt->var2,sizeof(dt->var2));
  18.    printf("Strncpy struct var2 = %s = %d\n",dt->var2,sizeof(dt->var2));
  19.  
  20.    fct(dt->var3,sizeof(dt->var3));
  21.    printf("Strncpy struct var3 = %s = %d\n",dt->var3,sizeof(dt->var3));
  22.  
  23.    fct(dt->var4,sizeof(dt->var4));
  24.    printf("Strncpy struct var4 = %s = %d\n",dt->var4,sizeof(dt->var4));
  25.  
  26.    printf("var1 = %s\nvar2 = %s\nvar3 = %s\nvar4 = %s\n",dt->var1,dt->var2,dt->var3,dt->var4);
  27. }
  28. int main() {
  29.    struct data mydata;
  30.    while (1) {
  31.       snd(&mydata);
  32.       printf("\n" );
  33.       sleep(1);
  34.    }
  35.  
  36.    return 0;
  37. }
 
Code :
  1. Strncpy struct var1 = ABCDE = 6
  2. Strncpy struct var2 = A = 2
  3. Strncpy struct var3 = ABCDEFGHIJK = 12
  4. Strncpy struct var4 = ABCDEFG = 8
  5. var1 = ABCDE
  6. var2 = A
  7. var3 = ABCDEFGHIJK
  8. var4 = ABCDEFG


Message édité par Nii le 16-05-2010 à 19:03:59
Reply

Marsh Posté le 16-05-2010 à 19:14:28    

Un tableau de taille N est indexé de 0 à N-1, donc pour avoir un comportement défini ton '\0' final doit se trouver en N-1, pas en N.


---------------
The truth is rarely pure and never simple (Oscar Wilde)
Reply

Marsh Posté le 16-05-2010 à 19:41:09    

Merci pour la confirmation.
Je pensais qu'une chaine justement allait jusqu'au bout de la déclaration (donc '\0' en fin de tableau).

Reply

Marsh Posté le 16-05-2010 à 23:28:32    

Nii a écrit :

Merci pour la confirmation.
Je pensais qu'une chaine justement allait jusqu'au bout de la déclaration (donc '\0' en fin de tableau).


 
Hé non. Le '\0' est placé juste après le dernier caractère de la chaine. Et il faut que la zone réceptrice soit assez grande pour stocker les caractères et le '\0'...


---------------
Vous ne pouvez pas apporter la prospérité au pauvre en la retirant au riche.
Reply

Marsh Posté le 17-05-2010 à 11:02:35    

Je me suis mal exprimé.
 
Pour moi char var[4] voulait dire :
var[0] = 'a';
var[1] = 'b';
var[2] = 'c';
var[3] = 'd';
var[4] = '\0';
 
Et pas :
var[0] = 'a';
var[1] = 'b';
var[2] = 'c';
var[3] = '\0';
var[4] = '';

Reply

Marsh Posté le 17-05-2010 à 11:09:31    

char var[4] c'est un tableau de 4 char, tout comme int var[4] est un tableau de 4 int ou struct foo var[4] est un tableau de 4 struct foo.  Il n'y a pas une exception pour char parce qu'on utilise souvent (mais pas exclusivement) les tableaux de char pour stocker des chaines terminees par un NUL.


---------------
The truth is rarely pure and never simple (Oscar Wilde)
Reply

Marsh Posté le 17-05-2010 à 11:17:34    

Citation :

Pour moi char var[4] voulait dire :  
var[0] = 'a';  
var[1] = 'b';  
var[2] = 'c';  
var[3] = 'd';  
var[4] = '\0';  
 
Et pas :  
var[0] = 'a';  
var[1] = 'b';  
var[2] = 'c';  
var[3] = '\0';  
var[4] = '';

En fait, ce n'est ni la première, ni la seconde solution car pour un tableau t déclaré avec une longueur n, son dernier élement est t[n-1] et non pas t[n]. Donc dire que var[4] = ''; n'a aucun sens.

Reply

Marsh Posté le 17-05-2010 à 16:48:00    

Citation :

car pour un tableau t déclaré avec une longueur n, son dernier élément est t[n-1] et non pas t[n].


Tu résume ce sur quoi je doutais, et tu met le doigt sur mon erreur.
Merci les gens.

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed