Je débute en C et J'essaie de faire un programme qui lance une commande OS et qui récupère la sortie de cette commande dans une variable.
J'ai un debut de programme qui marche mais il me reste 2 problèmes
1) j'arrive à lire la sortie de la commande caractère par caractère, mais quand je les concatene, j'ai une chaine de la bonne longueur mais tous les caracteres sont vides !
2) Il y a apparemment un problème dans mon utilisation de realloc car le programme se termine par un problème de mémoire
J'ai essayé pas mal de chose mais je ne vois vraiment pas de solution.
Quelqu'un pourrait il m'aider?
Merci d'avance
Voici mon programme:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int
main (void)
{
FILE *output;
char vc_car;
char *vc_str = NULL;
int vn_size;
// Execution de la commande OS
output = popen ("echo sortie_commande", "r");
if (!output) {
fprintf (stderr, "incorrect parameters or too many files.\n");
return EXIT_FAILURE;
}
vc_car = getc(output);
while (vc_car != EOF) {
if (!vc_str) {
// premiere allocation de memoire pour vc_str
vn_size = sizeof(vc_str);
vc_str = (char *) malloc (vn_size);
}
else {
// on augmente la taille de vc_str au fur et a mesure des caracteres lus
//
// vn_size = taille + 1 pour le caractere \0 indiquant la fin de la chaine
vn_size = sizeof(vc_str) + sizeof(vc_car) + 1;
vc_str = realloc (vc_str, vn_size);
if (vc_str == (char *)NULL) {
printf("Cannot allocate memory.\n");
}
}
vc_str = strcat(vc_str, &vc_car);
// Affichage
fprintf (stdout, "%c\n", vc_car);
fprintf (stdout, "x%sx\n", vc_str);
fprintf (stdout, "--------------\n");
vc_car = getc(output);
}
if (pclose (output) != 0)
{
fprintf (stderr, "Could not run more or other error.\n");
}
return EXIT_SUCCESS;
}
..... et la sortie a l'exécution :
vc_car : s
vc_str : x�x
--------------
vc_car : o
vc_str : x��x
--------------
*** glibc detected *** realloc(): invalid next size: 0x0804a0b8 ***
Abandon
# ...
Posté par M . Évalué à 2.
La fonction strcat() ajoute la chaîne src à la fin de la chaîne dest en
Or tu utilises un charactere en second argument.
// vn_size = taille + 1 pour le caractere \0 indiquant la fin de la chaine
vn_size = sizeof(vc_str) + sizeof(vc_car) + 1;
Ca fait beaucoup de "\0 indiquant la fin de la chaine" en comptant tout les tours de boucle.
# Hum, réfléchis
Posté par Raphaël G. (site web personnel) . Évalué à 2.
if (!vc_str) // !null
{
sizeof(vc_str); // sizeof(null)
}
Je pense pas que ça soit voulu...
Dégage ton sizeof(null) qui sert a rien et met direct :
vc_str = (char *) malloc (char);
Ensuite pour ton realloc arrête les bêtises :
vc_str = realloc (vc_str, vn_size); // stupide
Utilise :
vc_str = reallow(vc_str, strlen(vc_str+2)); // longueur vc_str+\0+prochain caractère.
Ensuite le test :
if (vc_str == (char *)NULL)
Le cast explicite est stupide, un NULL, restera TOUJOURS un NULL !
[^] # Re: Hum, réfléchis
Posté par Raphaël G. (site web personnel) . Évalué à 3.
Pas :
vc_str = (char *) malloc (char);
Mais :
vc_str = (char *)mallow(2*sizeof(char));
Et au lieu de strcat utilise ça :
vc_str[strlen(vc_str)] = vc_car;
vc_str[strlen(vc_str)] = '\0';
Ça permettra de copier le caractère a la place du \0 de la chaîne (strlen renvoie la taille totale, l'indexation commence a 0, donc tu tombe sur le \0 de fin de chaîne pile)
Bon après tu remplace le dernier caractère de la chaîne par un caractère nul, c'est une bonne idée je pense, car ça évite les ennuis (par exemple si ton système initialise pas la zone de mémoire malloqué à 0)
[^] # Re: Hum, réfléchis
Posté par Obsidian . Évalué à 4.
C'est vrai que les char mallow(), c'est bien meilleur. Surtout autour d'un feu de camp ! :-)
[^] # Re: Hum, réfléchis
Posté par Raphaël G. (site web personnel) . Évalué à 1.
Bah, c'est comme tout, on fait toujours de erreurs en codant quoique ce soit.
Après tout dépend la proportion, est-ce 1/10 000 comme les pro ou plus.
A savoir que j'ai pas fait de C depuis 2ans.
# merci...
Posté par startijenn . Évalué à 1.
[^] # Re: merci...
Posté par Raphaël G. (site web personnel) . Évalué à 2.
[^] # Re: merci...
Posté par Raphaël G. (site web personnel) . Évalué à 2.
#define _GNU_SOURCE
Avant l'include de stdio.h sinon gcc te sortira une erreur stricte comme quoi il est pas définis.
ps : pense a compiler tes programmes comme ceci :
$ gcc -Wall -str=c99 ton_fichier.c
[^] # Re: merci...
Posté par pasBill pasGates . Évalué à 3.
Une chose a comprendre c'est que ce ne'st pas parce que ton code ne plante pas qu'il est correct. Il pourrait crasher sur un systeme different, avec une configuration differente, si tu changes qqe chose ailleurs dans ton code (car le byte que tu ecrases apres le buffer y est utilise, ...)
Et en passant, si ton realloc rate, tu ne fais qu'afficher un message d'erreur, ton code continuera a s'executer et il plantera.
# getc renvoie un int
Posté par Batchyx . Évalué à 1.
chez moi EOF est un nombre négatif égal à -1, ça veut dire que si jamais la commande renvoie le caractère 255 alors le programme va considérer ça comme la fin du fichier.
chez d'autres ça peut avoir d'autres effets.
Suivre le flux des commentaires
Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.