C++ popen /fgets

Résolu
developper55 Messages postés 130 Statut Membre -  
 loupius -
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. developper55 Messages postés 130 Statut Membre 9
     
    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
    1. loupius
       
      Un détail, ne pas oublier de tester 'f_fichier' avant de l'utiliser dans le 'fscanf".
      0
  2. loupius
     
    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);.
    0
  3. mamiemando Messages postés 33228 Date d'inscription   Statut Modérateur Dernière intervention   7 943
     
    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
    0