Copy de tableau de caractère dans un tableau de caractère.

Copy de tableau de caractère dans un tableau de caractère. - C - Programmation

Marsh Posté le 04-11-2011 à 14:21:49    

Bonjour.
J'ai glané une info mais ça ne me suffit pas pour finaliser mon programme.
 
Voici ce que j'ai fait :

Code :
  1. #include <stdlib.h>
  2. #include <stdio.h>
  3. #include <string.h>
  4.  
  5. int main (int argc, char * argv[])
  6. {
  7.  char * FullText[80];
  8.  
  9.  if (argc < 2) {
  10.    return -1;
  11.  }
  12.  
  13.  int i;
  14.  int index = 0;
  15.  for (i = 1; i < argc; i++) {
  16.    int length = strlen(argv[i]);
  17.    if (index+length > 80) {
  18.      printf("Arguments to long!\n" );
  19.      break;
  20.    }
  21.    if (length != 0) {
  22.      printf("arg %d : %s ... done\n", i, argv[i]);
  23.      memcpy(&FullText[index], argv[i], length+1);
  24.      index = index + length;
  25.    }
  26.  
  27.  }
  28.  printf("%s\n", FullText);
  29.  return 0;
  30. }


 
Le but est de concaténer les argument de la ligne de commande dans un unique tableau et d'afficher ce dernière.
 
A l'exécution...

void:zero# ./main bonjour le monde !
arg 1 : bonjour ... done
arg 2 : le ... done
arg 3 : monde ... done
arg 4 : ! ... done
bonjour
void:zero#


 
Pourriez vous me donner un coup de main ? S'il vous plaît ?
Merci.

Reply

Marsh Posté le 04-11-2011 à 14:21:49   

Reply

Marsh Posté le 04-11-2011 à 14:44:41    

Quel est le problème ?
 
En tous cas, voici trois petites remarques :
 
1. Les chaines de caractères, qui se terminent par des zéros (cas habituel en C), se concatènent habituellement avec la fonction strcat(), ou sprintf(). La fonction memcpy() est à éviter.
 
2. Il faut tester > 79 car il ne faut pas oublier la place pour le zero de fin de chaîne.
 
3. Il ne faut confondre to et too. Ecrire printf("Arguments too long!\n" );.
 
Edit : 4. La déclaration char * FullText[80]; crée un pointeur sur une chaîne, et ne réserve donc que 4 ou 8 octets en mémoire. En fait, vous voulez réserver une chaîne de 80 octets. Donc il faut écrire char FullText[80];

Message cité 1 fois
Message édité par olivthill le 04-11-2011 à 14:48:25
Reply

Marsh Posté le 04-11-2011 à 14:46:16    

En oubliant pas les problématiques éventuelles d'unicode.
Tout les caractères ne sont pas codés sur 8 bits.


---------------
Töp of the plöp
Reply

Marsh Posté le 04-11-2011 à 15:03:40    

olivthill a écrit :

Quel est le problème ?
 
En tous cas, voici trois petites remarques :
 
1. Les chaines de caractères, qui se terminent par des zéros (cas habituel en C), se concatènent habituellement avec la fonction strcat(), ou sprintf(). La fonction memcpy() est à éviter.
 
2. Il faut tester > 79 car il ne faut pas oublier la place pour le zero de fin de chaîne.
 
3. Il ne faut confondre to et too. Ecrire printf("Arguments too long!\n" );.
 
Edit : 4. La déclaration char * FullText[80]; crée un pointeur sur une chaîne, et ne réserve donc que 4 ou 8 octets en mémoire. En fait, vous voulez réserver une chaîne de 80 octets. Donc il faut écrire char FullText[80];


 
 
Merci olivthill !
Pour le test > 79, c'est si je veux imprimer la chaîne ?
Parce que lorsque j'écris une chaîne littérale, j'écris pas le caractère null.
Je m'explique, j'exploite un programme qui affiche sur un écran LCD le texte passer en argument de fonction LCD_WriteString, que vous avez peut-être remarqué sur le forum ; Je ne met pas de caractère null en fin de chaîne, et ça marche.
 
Voici mon programme à présent, qui fonctionne grace à votre remarque 4, j'était dans l'interrogation sur ce point.

Code :
  1. #include <stdlib.h>
  2. #include <stdio.h>
  3. #include <string.h>
  4.  
  5. int main (int argc, char * argv[])
  6. {
  7.  char FullText[80];
  8.  
  9.  if (argc < 2) {
  10.    return -1;
  11.  }
  12.  
  13.  int i;
  14.  int index = 0;
  15.  for (i = 1; i < argc; i++) {
  16.    int length = strlen(argv[i]);
  17.    if (index+length > 80-(argc-2)) {
  18.      printf("Arguments too long!\n" );
  19.      break;
  20.    }
  21.    if (length != 0) {
  22.      printf("arg %d : %s ... done\n", i, argv[i]);
  23.      strcat(FullText, argv[i]);
  24.      if (i == argc-1)
  25.        break;
  26.      strcat(FullText, " " );
  27.      index = index + length;
  28.    }
  29.  }
  30.  printf("%s\n", FullText);
  31.  return 0;
  32. }


 

_darkalt3_ a écrit :

En oubliant pas les problématiques éventuelles d'unicode.
Tout les caractères ne sont pas codés sur 8 bits.


 
Merci pour cette remarque, mais que dois-je en déduire ?

Message cité 2 fois
Message édité par Profil supprimé le 04-11-2011 à 15:11:20
Reply

Marsh Posté le 04-11-2011 à 15:08:01    


Que dans ton cas cela va fonctionner: utiliser des copies de tableaux, des sprintf ou autre va suffire, parce que tes données sont des char, codés sur 8 bits.
 
Il existe d'autres fonctions de copies de chaînes qu'on utilisera dans un cas plus général, qui permettent de manipuler des chaînes de caractères, dont lesdits caractères sont codés sur plus de 8 bits. Les caractères unicodes en particulier.
 
Enfin, même si "ne pas mettre de '\0' terminal fonctionne" chez toi, dans un cas général, c'est une très mauvaise pratique en C.
Un chaîne de caractère, en C, se définit PAR son '\0', et se distingue par là d'une quelconque zone mémoire.


---------------
Töp of the plöp
Reply

Marsh Posté le 06-11-2011 à 09:11:02    


C'est un coup de bol dû à un effet de bord ailleurs ce qui fait que derrière la chaîne que tu as écrite, il y a des 0. Mais ne pas mettre les 0 à la fin, bravo, tu as fait ton premier bug permettant une attaque de sécurité par buffer overflow.
Et ça ne sera pas ton dernier, crois-moi, l'oubli ou l'écrasement du 0 terminal compte pour 50% des bugs en C. Si olivthill ne te l'avait pas signalé, tu te serais coltiné une belle séance de débogage pas piquée des hannetons (ce qui est formateur en soi).
edit: ah ben c'est gilou qui se la coltine, apparemment :o
bref, si tu as des comportements qui semblent aléatoires, tu peux déjà chercher du coté de:
a) des variables ou tableaux non initialisés
b) des écrasements mémoire dûs à l'oubli de 0 ou d'un mauvais calcul de longueur.
Déjà, débugge ton programme avant d'envoyer des chaînes incorrectes à ton afficheur, il se peut que ça soit une des raisons du comportement aléatoire.
Si tu es sous Linux, je te conseille très fortement d'utiliser valgrind, qui te détectera des erreurs dans ton programme même si tu as l'impression qu'il fonctionne bien. Tant que valgrind te pête une erreur, c'est qu'il y a un bug caché quelque part. Malheureusement, valgrind ne fonctionne que pour des programmes linux, mais c'est déjà ça.


Message édité par el muchacho le 06-11-2011 à 09:40:57

---------------
Les aéroports où il fait bon attendre, voila un topic qu'il est bien
Reply

Marsh Posté le 06-11-2011 à 10:12:26    

Je prends note. Merci El muchacho !

Reply

Sujets relatifs:

Leave a Replay

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