IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

GTK+ avec C & C++ Discussion :

[console]Récupérer la sortie d'un programme console (débutant)


Sujet :

GTK+ avec C & C++

  1. #1
    Membre averti
    Homme Profil pro
    Géomaticien
    Inscrit en
    Février 2010
    Messages
    63
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Géomaticien

    Informations forums :
    Inscription : Février 2010
    Messages : 63
    Par défaut [console]Récupérer la sortie d'un programme console (débutant)
    Bonjour à toute la communauté,

    Voilà, je dois développer un programme qui sera une sorte de frontend crée à l'aide de Glade pour un autre programme console (qui n'a pas été développé par moi). A ce dernier je dois lui passer 2 paramètres pour qu'il m'affiche une liste en sortie que je dois récupérer pour l'afficher dans un listview ultérieurement. Etant débutant en GTK et en C en général, ma plus grande interrogation est de savoir comment récupérer la sortie de ce programme. Ma piste se situe ici : http://www.gidforums.com/t-3369.html

    J'ai donc plusieurs questions à ce sujet :
    - est-ce d'ailleurs la bonne piste, celle de la fonction pipe ?
    - n'est pas un peu trop complexe pour un débutant ?
    - quels conseils me donneriez-vous sur ce sujet ?

    Voilà tout ce que je peux dire pour le moment.

    D'avance merci des réponses.

  2. #2
    Expert confirmé
    Avatar de gerald3d
    Homme Profil pro
    Conducteur de train
    Inscrit en
    Février 2008
    Messages
    2 308
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Côte d'Or (Bourgogne)

    Informations professionnelles :
    Activité : Conducteur de train
    Secteur : Transports

    Informations forums :
    Inscription : Février 2008
    Messages : 2 308
    Billets dans le blog
    5
    Par défaut
    C'est la bonne piste. Maintenant GTK+ s'appuie sur la librairie Glib qui dispose de fonctions adéquates pour ce que tu veux faire : les spawning-processes.

  3. #3
    Membre averti
    Homme Profil pro
    Géomaticien
    Inscrit en
    Février 2010
    Messages
    63
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Géomaticien

    Informations forums :
    Inscription : Février 2010
    Messages : 63
    Par défaut
    Bonjour,

    Donc c'est plus simple alors... Merci. Je dois donc utiliser g_spawn_sync () pour mes besoins. Peut-être avez-vous des recommandations pour que je ne fasse pas n'importe quoi n'importe comment ? Merci.

  4. #4
    Membre averti
    Homme Profil pro
    Géomaticien
    Inscrit en
    Février 2010
    Messages
    63
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Géomaticien

    Informations forums :
    Inscription : Février 2010
    Messages : 63
    Par défaut
    OK, bon j'ai en fait utiliser g_spawn_command_line_sync () qui s'est avéré encore plus simple, tout se passe bien, la commande est bien passé ainsi :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    g_spawn_command_line_sync (command, &result, NULL, &exit_status, &err)
    La sortie du programme sollicité se retrouve dans result un tableau de char donc. Cette sortie se présente ainsi :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Id_de_l'objet -tabulation- Nom_de_l'objet
    En donnant un exemple pour être plus concret :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    000	Trucmuche
    001	Trukchouette
    002	Bidule
    Je veux l'intégrer dans une liste GtkTreeView avec une colonne ID de type gchararray, et une colonne Nom de type gchararray aussi. Il me faut donc traiter result. Quelle est la meilleure méthode : remplir la liste séquentiellement, càd on lit une ligne, on la traite puis on l'affiche dans une ligne du GtkTreeView ; ou bien créer un tableau qui contient les infos du result puis remplir à la fin le GtkTreeView. Comment y parvenir ?

  5. #5
    Membre averti
    Homme Profil pro
    Géomaticien
    Inscrit en
    Février 2010
    Messages
    63
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Géomaticien

    Informations forums :
    Inscription : Février 2010
    Messages : 63
    Par défaut
    Bon voilà, j'ai avancé un peu depuis, mais d'abord je ne suis pas sûr que de ce que j'ai fait, et d'autre part je ne sais pas trop comment afficher dans mon GtkTreeView.

    Edit : bon j'arrive à afficher dans le GtkTreeview, j'ai compris le système, mais le découpage de la chaîne de caractère s'effectue mal.

    Voici mon code :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
     
     
    /* NOTE : ListStore1 est un GTK_LIST_STORE récupéré lors du chargement de l'interface */
     
    void
    strout_to_list (gchar *list)
    {
    	char *ID;
    	char *NameObj;
     
    	gtk_list_store_clear (ListStore1); /* on efface la liste avant de la remplir */
     
    	while (list != NULL)
    	{
    		GtkTreeIter pIter;
     
    		ID = strtok (list, "\t"); /* on récupère l'id de chaque ligne */
     
    		list = strtok (NULL, "\t"); /* on efface l'id pour pouvoir poursuivre l'extraction de données */
     
    		NameObj = strtok (list, "\n"); /* on récupère le nom de l'objet de chaque ligne */
     
    		list = strtok (NULL, "\n"); /* on efface le nom d'objet pour pouvoir poursuivre l'extraction de données */
     
    		gtk_list_store_append (ListStore1,  &pIter); /* on crée la ligne qui accueillera les données */
     
    		gtk_tree_store_set (ListStore1, pIter , 0, ID, 1, NameObj, -1); /* Ajouter les données de la ligne*/
     
    	}
    }
    C'est le fait qu'il y a deux séparateurs (\t et \n) dans la chaîne et du coup ça s'embrouille.

  6. #6
    Membre averti
    Homme Profil pro
    Géomaticien
    Inscrit en
    Février 2010
    Messages
    63
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Géomaticien

    Informations forums :
    Inscription : Février 2010
    Messages : 63
    Par défaut
    Bon, en fait je n'avais pas bien saisi le fonctionnement de strtok, je ne savais pas qu'on pouvait y appliquer 2 séparateurs différents en même temps, du coup cela simplifie grandement la tâche (1 boucle au lieu de 2).

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    stdout_to_list (gchar *list)
    {
    	gchar *ID;
    	gchar *NameObj;
    	gchar *Separ = "\t\n"; /* les 2 séparateurs, tab et retour de ligne */
    	gchar *Ligne;
    	gint i = 1;
    	GtkTreeIter pIter;
     
    	gtk_list_store_clear (ListStore1); /* on efface la liste avant de la remplir */
     
    	Ligne = strtok (list, Separ); /* initialisation de l'extraction des mots (1er mot) */
     
    	while(Ligne != NULL)
    	{
    		if (i > 1) /* le 1er mot étant déjà extrait, l'instruction est uniquement exécutée aux mots suivants */
    		{
    			Ligne = strtok (NULL, Separ);
    		}
     
    		ID = Ligne; /* récupération de l'id de l'objet */
     
    		Ligne = strtok (NULL, Separ); /* on passe à l'extraction du nom de l'objet */
     
    		NameObj = Ligne; /* récupération du nom de l'objet */
     
    		if (ID != NULL && NameObj !=NULL) /* test pour savoir si la ligne est vide, si non, alors on ajoute à la liste ListStore1 */
    		{
    			gtk_list_store_append (ListStore1,  &pIter);
     
    			gtk_list_store_set (ListStore1, &pIter, 0, ID, 1, NameObj, -1);
     
    			i++;
    		}
    		else /* si la ligne est vide, c'est qu'on arrive à la fin ; on quitte alors la boucle, inutile de continuer */
    		{
    			break;
    		}
    	}
     
    	return 0;
    }

    Je ne met pas tout de suite en résolu, j'attends des remarques éventuelles.

  7. #7
    Modérateur

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juin 2009
    Messages
    1 395
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2009
    Messages : 1 395
    Par défaut
    Plusieurs remarques :
    1. je pense que tu oublies de libérer la mémoire allouée par strtok
    2. regarde la doc de g_strsplit
    3. ton break ne sert à rien puisque tu va sortir de la boucle juste après, sans rien faire
    4. découpe ton traitement pour que chaque boucle que tu fais soit pour gérer un token, et non une ligne, ou mieux (parce que tu ne risqueras pas de te gaufrer s'il manque un champ dans une ligne), deux boucles imbriquées, une qui cherche les lignes et l'autre les champs dans chaque ligne.
    5. Le nom de ta variable Ligne est trompeur, tu mets des tokens dedans, pas des lignes.

  8. #8
    Membre averti
    Homme Profil pro
    Géomaticien
    Inscrit en
    Février 2010
    Messages
    63
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Géomaticien

    Informations forums :
    Inscription : Février 2010
    Messages : 63
    Par défaut
    Bonsoir,

    Citation Envoyé par liberforce Voir le message
    Plusieurs remarques :
    1. je pense que tu oublies de libérer la mémoire allouée par strtok
    Je me doutais bien que j'avais oublié quelque chose....

    Citation Envoyé par liberforce Voir le message
    2. regarde la doc de g_strsplit
    Merci, je ne connaissais pas. Cependant, au cours des recherches, j'ai trouvé pas mal de fonctions qui auraient pu me servir, j'ai choisi celle qui me paraissait la plus simple d'utilisation. Là aussi, honte à moi

    Citation Envoyé par liberforce Voir le message
    3. ton break ne sert à rien puisque tu va sortir de la boucle juste après, sans rien faire
    Le problème, c'est que lors des tests le GtkTreeView était ajouté à la fin systématiquement d'une ou deux lignes vides, et pour l'id, et pour le nom de l'objet, sans pour autant que cela ait de conséquence sur les autres lignes. C'est pour cela que j'ai rajouté un break. J'ai peut-être mal fait, mais là je ne vois vraiment pas comment m'en passer...

    Citation Envoyé par liberforce Voir le message
    4. découpe ton traitement pour que chaque boucle que tu fais soit pour gérer un token, et non une ligne, ou mieux (parce que tu ne risqueras pas de te gaufrer s'il manque un champ dans une ligne), deux boucles imbriquées, une qui cherche les lignes et l'autre les champs dans chaque ligne.
    Je pense que c'est le nom de ma variable qui te perturbe, comme tu le signale plus loin. Je rectifierai, ça risque de me tromper aussi. C'est qu'au début je partais pour 2 boucles car je pensais qu'il fallait traiter les séparateurs... séparément, soit en gros faire un premier découpage en lignes, d'où le nom de ma variable. Mes excuses si cela perturbe.

    Citation Envoyé par liberforce Voir le message
    5. Le nom de ta variable Ligne est trompeur, tu mets des tokens dedans, pas des lignes.
    C'est entendu.

  9. #9
    Membre averti
    Homme Profil pro
    Géomaticien
    Inscrit en
    Février 2010
    Messages
    63
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Géomaticien

    Informations forums :
    Inscription : Février 2010
    Messages : 63
    Par défaut
    C'est vrai que l'utilisation uniquement de fonctions Glib est diablement intéressante dans le cas d'une application GTK ! Je vais sans aucun doute l'utiliser au moment d'optimiser mon programme. Merci à vous !

  10. #10
    Membre averti
    Homme Profil pro
    Géomaticien
    Inscrit en
    Février 2010
    Messages
    63
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Géomaticien

    Informations forums :
    Inscription : Février 2010
    Messages : 63
    Par défaut
    Bon, il y a un adage du petit programmeur qui a germé dans mon esprit, mais peut-être je n'en ai pas l'exclusivité, c'est "plus il y a de solutions, plus on rit" ; alors je partage la version que j'ai fait avec g_strsplit, d'avis elle me paraît plus simple et compréhensible d'utilisation que strtok, on comprend mieux son fonctionnement. Chacun fera son opinion sur strtok et g_strsplit.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    int
    stdout_to_list (gchar *StrStdOut, GtkListStore *ListStore)
    {
    	gchar		*ID;
    	gchar		*NameObj;
    	gchar		*SeparLines = "\n";
    	gchar		*SeparCols = "\t";
    	gchar		**Cols; /* double pointeur car la valeur retournée par g_strsplit est un tableau de string */
    	gchar		**Lines; /* idem */
    	gint		i = 0;
    	GtkTreeIter	pIter;
     
    	while (gtk_events_pending()) gtk_main_iteration(); /* Si l'exécution est longue, cela permet de garder la main pour l'interface */
     
    	gtk_list_store_clear (ListStore); /* on efface la liste avant d'accueillir les données */
     
    	Lines = g_strsplit (StrStdOut, SeparLines, -1); /* on découpe en lignes le stdout du programme */
     
    	while (Lines[i] != NULL) /* traitement par ligne */
    	{
    		Cols = g_strsplit (Lines[i], SeparCols, -1); /* on sépare les 2 entités */
     
    		if (Cols[0] != NULL && Cols[1] != NULL) /* test si la ligne n'est pas vide */
    		{
    			ID = Cols[0]; /* on récupère alors l'id... */
    			NameObj = Cols[1]; /* ...puis le nom de l'objet */
     
    			gtk_list_store_append (ListStore,  &pIter); /* préparation de la ligne qui accueillera la donnée en cours */
    			gtk_list_store_set (ListStore, &pIter, 0, ID, 1, NameObj, -1); /* on y stocke */
     
    			g_strfreev (Cols); /* libération de la ligne de donnée testée */
    			i++;
    		}
    		else
    		{
    			g_strfreev (Cols); /* libération de la ligne de donnée testée */
    			break;
    		}
    	}
     
    	g_strfreev (Lines); /* libération de toutes les lignes */
     
    	return 0;
    }

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 3
    Dernier message: 25/11/2014, 11h57
  2. récupérer la sortie d'un programme externe
    Par diodio13fr dans le forum Débuter avec Java
    Réponses: 2
    Dernier message: 23/11/2009, 23h15
  3. Réponses: 15
    Dernier message: 15/06/2009, 17h35
  4. recuperer sortie d'un programme console
    Par jmjmjm dans le forum C++
    Réponses: 10
    Dernier message: 27/02/2008, 15h21
  5. [C#] Récupérer la sortie d'un programme DOS
    Par olivier_23 dans le forum Windows Forms
    Réponses: 7
    Dernier message: 12/08/2006, 13h54

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo