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

C Discussion :

fonction retournant un tableau multidimensionnel: Problème!


Sujet :

C

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Février 2004
    Messages
    7
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2004
    Messages : 7
    Par défaut fonction retournant un tableau multidimensionnel: Problème!
    Bonjour à toute la communauté,

    Mon souci est au niveau d'une valeur de retour d'une fonction. En effet, ma fonction est faite pour traiter n'importe quelle requête MySQL qui est supposée renvoyer quelque chose (une requête select par exemple).
    J'aimerai donc que ma fonction me retourne un tableau de ce type:
    xxxxxxxx| champ1 | champ2 | ............ | champ X
    ligne1 | valeur | valeur |............. | valeur X
    ligne 2 | valeur | valeur |............. | valeur X
    ligne X | valeur | valeur |............. | valeur X

    Mon problème est donc de pouvoir utiliser en dehors de la fonction le tableau que je constitue à l'intérieur de la fonction.
    Voici mon code qui est totalement fonctionnel SAUF pour la valeur de retour. En gras dans le code, c'est les instructions qu'il faut sans doute modifier pour que la fonction fonctionne correctement. Mais comment les modifier...
    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
    char **  mysql_requete_select(MYSQL* connexion, char* requete) {
    	MYSQL_RES *resultat;
    	MYSQL_ROW ligne;
    	my_ulonglong nb_ligne; 
    	int nb_champ;
    	int indice_ligne;
    	int indice_champ;
    	
    	if(mysql_query(connexion, requete)) {
    		printf(mysql_error(connexion));
    	}
    	resultat = mysql_store_result(connexion);
    	nb_ligne = mysql_num_rows(resultat);
    	nb_champ = mysql_num_fields(resultat);
    	char *tab_retour[nb_ligne][nb_champ];
    	
    	char *pchaine;
    	for(indice_ligne=0; (ligne = mysql_fetch_row(resultat)); indice_ligne++ ) {
    		for(indice_champ=0; indice_champ<nb_champ; indice_champ++) {
    			pchaine = malloc(strlen(ligne[indice_champ]) + 1);
    			strcpy(pchaine, ligne[indice_champ]);
    			tab_retour[indice_ligne][indice_champ] = pchaine;
    		}
    	}
    	return tab_retour;
    La variable tab_retour est EXACTEMENT le tableau que je veux avoir!
    Mon problème est donc de savoir comme pouvoir récupérer ce tableau afin de l'utiliser en dehors de cette fonction... Le mystère est là... (enfin pour moi )

    Si quelqu'un a la réponse, je serai ravi

  2. #2
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 395
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 395
    Par défaut
    Ouh, tu cherches à retourner un VLA...
    D'une part ce n'est pas évident que ce soit possible, d'autre part, un VLA est une variable locale, et on ne retourne jamais l'adresse d'une variable locale...
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  3. #3
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Février 2004
    Messages
    7
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2004
    Messages : 7
    Par défaut
    D'accord. Mes warnings sur gcc comme quoi on ne pouvait pas retourner une variable locale étaient donc véridiques. Zut.

    Il doit bien avoir une solution à mon problème, non? En passant en paramètre de la fonction un pointeur mais en faisant quoi après

    Sur ce coup j'ai du mal... Un expert dans la salle? (ou quelqu'un ayant la réponse tout simplement )

  4. #4
    Membre confirmé
    Profil pro
    Inscrit en
    Juin 2004
    Messages
    145
    Détails du profil
    Informations personnelles :
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations forums :
    Inscription : Juin 2004
    Messages : 145
    Par défaut
    Tu peux initialiser ton tableau à 2 dimensions dans la fonction appellante et le passer en paramètre ta fonction :

    char tab_retour[nb_ligne][nb_champ];
    Le prototype de ta fonction sera :
    void mysql_requete_select(MYSQL* connexion, char* requete, char **tab);

  5. #5
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 395
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 395
    Par défaut
    Tu peux initialiser ton tableau à 2 dimensions dans la fonction appellante
    Ben non, les dimensions sont calculées dynamiquement dans la fonction appelée...
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  6. #6
    Expert confirmé
    Avatar de diogene
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Juin 2005
    Messages
    5 761
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2005
    Messages : 5 761
    Par défaut
    Tu peux initialiser ton tableau à 2 dimensions dans la fonction appellante et le passer en paramètre ta fonction :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    char tab_retour[nb_ligne][nb_champ];
    Le prototype de ta fonction sera :
    void mysql_requete_select(MYSQL* connexion, char* requete, char **tab);
    Ce prototype ne permet pas de passer le tableau tab_retour dont le type n'est absolument pas char**
    D'accord. Mes warnings sur gcc comme quoi on ne pouvait pas retourner une variable locale étaient donc véridiques. Zut.
    Plus précisément, comme le dit Medinoc , ne pas retourner l'adresse d'une variable locale

  7. #7
    Expert éminent
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 68
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Par défaut
    Citation Envoyé par goutbouyo
    Tu peux initialiser ton tableau à 2 dimensions dans la fonction appellante et le passer en paramètre ta fonction :

    char tab_retour[nb_ligne][nb_champ];
    Le prototype de ta fonction sera :
    void mysql_requete_select(MYSQL* connexion, char* requete, char **tab);
    Il faut arrêter avec ça. Un char ** n'a jamais été le bon type pour un tableau lineaire à 2 dimensions. Merci de ne pas répondre n'importe quoi, c'est déjà assez compliqué de répondre ce qu'il faut...

    http://emmanuel-delahaye.developpez.....htm#param_tab

  8. #8
    Membre éclairé
    Profil pro
    Inscrit en
    Septembre 2005
    Messages
    66
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2005
    Messages : 66
    Par défaut
    Citation Envoyé par Emmanuel Delahaye
    Il faut arrêter avec ça. Un char ** n'a jamais été le bon type pour un tableau lineaire à 2 dimensions. Merci de ne pas répondre n'importe quoi, c'est déjà assez compliqué de répondre ce qu'il faut...

    http://emmanuel-delahaye.developpez.....htm#param_tab
    En fait, après lecture d'un paragraphe sur le sujet, est-ce mauvais que le type du paramètre de la fonction soit char** ?

    pour la déclaration, OK, ça change. mais moi je ne vois pas le problème pour le type du paramètre d'une fonction.

  9. #9
    Expert confirmé
    Avatar de Thierry Chappuis
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Mai 2005
    Messages
    3 499
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : Suisse

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Industrie Pharmaceutique

    Informations forums :
    Inscription : Mai 2005
    Messages : 3 499
    Par défaut
    Ne peux -tu pas faire une allocation dynamique d'un tableau bidimensionnel de chaînes de caractères (avec malloc) à l'intérieur de ta fonction et retourner son adresse?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
            char ***tab_retour;
    	tab_retour = malloc(nb_ligne*sizeof(*tab_retour));
    	if (tab_retour == NULL){
    		exit(1);
    	}
    	for (i=0; i<nb_ligne; i++){
    		*(tab_retour+i) = malloc(nb_champs*sizeof(**tab_retour));
    		if(*(tab_retour+i) == NULL){
                            exit(1);
                    }
    	}
            /*...*/
            return tab_retour;
    "The most important thing in the kitchen is the waste paper basket and it needs to be centrally located.", Donald Knuth
    "If the only tool you have is a hammer, every problem looks like a nail.", probably Abraham Maslow

    FAQ-Python FAQ-C FAQ-C++

    +

  10. #10
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Février 2004
    Messages
    7
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2004
    Messages : 7
    Par défaut
    Merci à tous! J'utilise ta solution mujigka et cela fonctionne à merveille!
    L'idée de faire comme ça m'a traversé l'esprit un instant mais manier des pointeurs sur 3 tableaux différents, non merci Mais comme la solution est toute prête, je prends volontier.

    Petite dernière question: Pour désallouer toute cette mémoire, je peux me contenter d'un free sur tab_retour ou je doit faire un free sur tab_retour[0][0], sur tab_retour[0] et tab_retour?

  11. #11
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Février 2004
    Messages
    7
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2004
    Messages : 7
    Par défaut
    Euh là en fait en réfléchissant, j'ai l'impression que ça va être difficile pour moi de désallouer la mémoire avec la méthode de mujigka étant donné que je n'ai pas les dimensions du tableaux en dehors de la fonction.

    Je me trompe?

  12. #12
    Expert éminent
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 68
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Par défaut
    Citation Envoyé par mujigka
    Ne peux -tu pas faire une allocation dynamique d'un tableau bidimensionnel de chaînes de caractères (avec malloc) à l'intérieur de ta fonction et retourner son adresse?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
            char ***tab_retour;
    Pourquoi 3 étoiles pour un tableau de pointeur ?

    Tout le monde est tombé sur la tête ce soir ou quoi ?

  13. #13
    Membre éclairé
    Profil pro
    Inscrit en
    Septembre 2005
    Messages
    66
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2005
    Messages : 66
    Par défaut
    Pourquoi 3 étoiles pour un tableau de pointeur ?
    d'ailleurs je crois avoir déjà fait la gaffe, et je me demande si le compilateur accepte ?

    je voudrais bien une solution à ce problème aussi. Elle est bien non la méthode de goutbouyo (à part l'erreur de type pour le tableau à 2 dimension) ?

Discussions similaires

  1. Réponses: 24
    Dernier message: 24/05/2006, 19h19
  2. Fonction retournant un tableau initialisé
    Par ero-sennin dans le forum Delphi
    Réponses: 6
    Dernier message: 13/05/2006, 16h05
  3. [TP] Fonction retournant un tableau
    Par molesqualeux dans le forum Turbo Pascal
    Réponses: 8
    Dernier message: 07/05/2006, 01h01
  4. PB avec fonction retournant un tableau
    Par T-B dans le forum Langage
    Réponses: 2
    Dernier message: 27/01/2006, 22h01
  5. fonction retournant un tableau
    Par Jero13 dans le forum C
    Réponses: 7
    Dernier message: 22/11/2005, 11h14

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