C++ popen /fgets

Résolu
Bonjour,
pour récupérer les résultat de la commade system :
string ppp="ps ax";
int pid[10];
pid[1]=pid[2]=0;
int i=1;
FILE *fp;
char command[9];
fp = popen(ppp.c_str(), "r");
while( fgets(command, 9, fp)){
pid[i]=atoi(command);
i=i+1;
}
pclose(fp);
if (pid[2]==0) return 0;
else return 1;
}
//////////////// récupere deux lignes

// exemple dans https://linuxfr.org/forums/programmation-c--2/posts/lecture-dun-fichier-texte-par-colonne-d%C3%A9butant

void get_values(char* ligne, float *v1, float *v2)
{
char *tmp;
char *result;
/* strtok modifie son premier argument,
on travaille donc sur une variable temporaire */
strcpy(tmp, ligne);

result = strtok(tmp, "\t, ");
if(result != NULL) {
sscanf(result, "%f", v1);

result = strtok(NULL, "\t ");
if(result != NULL) {
sscanf(result, "%f", v2);
}
}
}
int main (int argc, char* argv[])
{
int i;
int pid[10];
int ppid[10];
FILE *fp;
float *value1 = NULL,
*value2 = NULL;
char line[256] = "";
fp = popen("ps -o pid,ppid", "r");
///le ps -o pid,ppid =>>>>
PID PPID
12562 12561
26898 12562
if (fp == NULL) return -1;
//value1 = malloc(10 * sizeof *value1);
//value2 = malloc(10 * sizeof *value2);

while((fgets(line, 256, fp) != NULL)) {
get_values(line, &(value1[i]), &(value2[i]));
i++;
}
/* et bien sur on libere la memoire */
free(value1);
value1 = NULL;
free(value2);
value2 = NULL;
fclose(fp);
fp = NULL;

return 0;
}

// j'ai Segmentation fault
et en mode debug:
[Thread debugging using libthread_db enabled]
[New Thread 16384 (LWP 26834)]
Detaching after fork from child process 26854.

Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread 16384 (LWP 26834)]
0x00270328 in _IO_vfscanf_internal () from /lib/i686/libc.so.6

quelqu1 peut m'aider,,
merci par avance,
Bob
Configuration: Linux Redhat EL4
g++3

3 réponses

  1. Mensieur,

    été trop facile, il suffit d'utiliser fopen(ou popen) avec fscan,,,, et cé tout,,,,

    char var1[9]="";
    char var2[9]="";

    FILE *f_fichier;
    f_fichier=popen("fichier.txt","r" );
    fscanf(f_fichier,"%s %s",var1,var2);
    printf("%s,%s\n",var1,var2);
    return 0;
    }

    merci pour loupius, mamiemando,
    merci tout le monde
    @+
    1. Un détail, ne pas oublier de tester 'f_fichier' avant de l'utiliser dans le 'fscanf".
  2. Modérateur
    Sinon il n'est pas plus simple de faire un execvp dont tu rediriges les résultats dans un fichier que tu lis après exécutaion de la commande ?
    http://www.linux-kheops.com/doc/man/manfr/man-ascii-0.9/man3/execvp.3.txt.html

    (mando@aldur) (~) $ df -h 1>pouet.txt 2>pouet.txt
    (mando@aldur) (~) $ cat pouet.txt
    Sys. de fich.         Tail. Occ. Disp. %Occ. Monté sur
    /dev/hda2              27G   15G   11G  60% /
    tmpfs                 253M     0  253M   0% /lib/init/rw
    udev                   10M  100K   10M   1% /dev
    tmpfs                 253M     0  253M   0% /dev/shm
    /dev/hda1             9,8G  3,7G  6,1G  38% /mnt/ntfs
    /dev/hdb1              77G   51G   27G  66% /mnt/vfat
    

    Donc si tu reprends cet exemple la commande df -h voit la sortie d'erreur et la sortie standard redirigées vers plop. Il suffit d'appeler ta commande de la même façon et de lire pouet.txt après coup... non ?

    Bonne chance
    1. Classique, segmentation fault -> mauvaise allocation pointeur (dans 99 % des cas) !
      Alors où se trouve l'erreur ?
      Dans la fonction void get_values(char* ligne, float *v1, float *v2), il y a la fonction sscanf(result, "%f", v1); qui est bien utilisée et qui suppose que 'v1' est un pointeur sur une case mémoire (ici de type float).
      Or get_values(line, &(value1[i]), &(value2[i])); envoie bien un pointeur mais float *value1 = NULL; initialise un pointeur mais n'alloue aucune case mémoire ===>>> plantage assuré.
      Je ne vais pas plus loin; il y a peut-être d'autres erreurs... mais il faut d'abord corriger celle-ci.
      Evidemment l'erreur est la même pout 'v2'.
      Bon courage.
      Nota: A la place de get_values(line, &(value1[i]), &(value2[i]));, autant mettre get_values(line, value1, value2);.