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 :

Initialiser un tableau => base de donnée mysql/mariaDb


Sujet :

C

  1. #1
    Membre régulier
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    210
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Avril 2007
    Messages : 210
    Points : 91
    Points
    91
    Par défaut Initialiser un tableau => base de donnée mysql/mariaDb
    Bonjour à tous,

    Mon petit soucis du jour : j'aimerai récupérer des données données dans une tableau 2d " tableau[i][j] ". Je ne sais comment initialiser mon tableau car je ne connais pas le nombre de ligne que va me donner ma requête à la base de donnée .... Les informations récupérées "row[2]" sont de type binary(64) dans la base de donnée.

    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
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    #include <stdio.h>
    #include <errno.h>
    #include <string.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <sys/inotify.h>
    #include <time.h> 
    //mysql
    #include <mariadb/mysql.h>
     
    int main()
    {
     
    MYSQL *conn;
    MYSQL_RES *res;
    MYSQL_ROW row;
     
    char *server = "localhost";
    char *user = "***";
    char *password = "***"; 
    char *database = "TEST";
     
    int row_precedent;
    int i,j = 0;
     
    conn = mysql_init(NULL);
       if (!mysql_real_connect(conn, server,
             user, password, database, 0, NULL, 0)) {
          fprintf(stderr, "%s\n", mysql_error(conn));
          exit(1);
       }  
    	 char insertion[300];
    	 sprintf(insertion, "SELECT * FROM BDtest WHERE temps > %d", (int)time(NULL));
    	 if (mysql_query(conn, insertion)) {
          fprintf(stderr, "%s\n", mysql_error(conn));
          exit(1);
       }
       res = mysql_use_result(conn);
     
       while ((row = mysql_fetch_row(res)) != NULL)
           {
          printf("%s %s %s \n", row[0],row[1],row[2]);
     
    		if(row[1]!=row_precedent)
    		{
    		j=0;
    		tableau[i][j]=row[2];
    		i++;
                    row[1]=row_precedent;
    		} 
     		else
    		{
    		tableau[i][j]=row[2];
    		j++;
    		}
    	}
     mysql_free_result(res);
     mysql_close(conn);	
    //fin connexion mysql	
     
    }
    Merci de votre aide et bon WE

  2. #2
    Membre habitué Avatar de racine carrée
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2018
    Messages
    156
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 23
    Localisation : France, Maine et Loire (Pays de la Loire)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2018
    Messages : 156
    Points : 137
    Points
    137
    Par défaut
    Bonjour,
    si tu ne connais pas la dimension à l'avance, soit tu utilises un tableau statique dont la taille vaut le maximum de la longueur possible des données (mais ce n'est pas forcément une bonne solution), soit tu utilises un tableau dynamique:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    #include <vector>
    vector<type_donnée> tableau(longueur_tableau); //longueur_tableau est int (et non un const int)
    Bon courage.

  3. #3
    Membre habitué Avatar de racine carrée
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2018
    Messages
    156
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 23
    Localisation : France, Maine et Loire (Pays de la Loire)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2018
    Messages : 156
    Points : 137
    Points
    137
    Par défaut
    Ici ce sera donc le type vector<vector<string>> qu'il faudra utiliser (si les données à rentrer dans le tableau sont des chaines de caractère).

  4. #4
    Expert éminent sénior
    Homme Profil pro
    Analyste/ Programmeur
    Inscrit en
    Juillet 2013
    Messages
    4 629
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Analyste/ Programmeur

    Informations forums :
    Inscription : Juillet 2013
    Messages : 4 629
    Points : 10 554
    Points
    10 554
    Par défaut
    Citation Envoyé par racine carrée Voir le message
    soit tu utilises un tableau dynamique
    Citation Envoyé par racine carrée Voir le message
    Ici ce sera donc le type vector<vector<string>> qu'il faudra utiliser (si les données à rentrer dans le tableau sont des chaines de caractère).


    Cela n'existe pas en C - en C++ oui avec std::vector et std::string (<- liens cplusplus.com en anglais)

    il faut y aller à coup de malloc/ realloc (<- liens cplusplus.com en anglais)

    Pour un exemple, regarde la structure t_list_keys et la fonction list_keys_add_one_key dans mon code dans ce fil de discussion (<- lien)

  5. #5
    Membre habitué Avatar de racine carrée
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2018
    Messages
    156
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 23
    Localisation : France, Maine et Loire (Pays de la Loire)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2018
    Messages : 156
    Points : 137
    Points
    137
    Par défaut
    Ah désolé j'avais pas fait gaffe qu'on était en C 😂.
    Du coup y a moyen d'utiliser des listes chainées (pour manipuler le tableau on manipule le pointeur du premier élément du tableau, chaque élément du tableau contient l'élément qu'on veut y mettre + un pointeur vers l'élément suivant, le dernier élément contient un pointeur null en plus de l'élément qu'il doit contenir, pour indiquer qu'on est arrivé à la fin du tableau).

  6. #6
    Rédacteur/Modérateur


    Homme Profil pro
    Network game programmer
    Inscrit en
    Juin 2010
    Messages
    7 115
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : Canada

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 115
    Points : 32 963
    Points
    32 963
    Billets dans le blog
    4
    Par défaut
    Est-ce que tu comptes récupérer de très larges sets de données ?
    Si non, utilise mysql_store_result puis mysql_num_rows.
    Pensez à consulter la FAQ ou les cours et tutoriels de la section C++.
    Un peu de programmation réseau ?
    Aucune aide via MP ne sera dispensée. Merci d'utiliser les forums prévus à cet effet.

  7. #7
    Membre habitué Avatar de racine carrée
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2018
    Messages
    156
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 23
    Localisation : France, Maine et Loire (Pays de la Loire)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2018
    Messages : 156
    Points : 137
    Points
    137
    Par défaut
    Voici un petit exemple de liste chainée pouvant contenir des chaines de caractères (de 300 caractères max, comme il semble que cela soit nécessaire dans ton code source).
    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
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
     
    typedef struct elem elem;
    typedef char valeur[300];
    typedef struct elem{
        valeur chaine;
        elem* suivant;
    } *tableau, *Pelem;
     
    tableau ajoute(tableau tab,valeur chaine){
        if(tab){
            tab->suivant=ajoute(tab->suivant,chaine);
        } else {
            tab = malloc(sizeof(elem));
            strcpy(tab->chaine,chaine);
            tab->suivant=NULL;
        }
        return tab;
    }
     
    void affiche(tableau tab){
        if(tab){
            printf("adresse: %i\n",tab);
            printf("%s\n",tab->chaine);
            printf("adresse suivant: %i\n",tab->suivant);
            affiche(tab->suivant);
        }
    }
     
    int main()
    {
        tableau tab=NULL;
        tab=ajoute(tab,"ligne 1");
        affiche(tab);
        printf("\n\n");
        tab=ajoute(tab,"ligne 2");
        affiche(tab);
        return 0;
    }
    Pour l'adapter à ton cas il faudrait avoir un tableau de tableaux de chaines de caractères, donc je pense qu'un moyen pourrait être de créer une liste chainées contenant des pointeurs vers des tableau (de type tableau dans ce code source), et ensuite de créer les fonctions qui vont bien pour récupérer une élément du tableau quand nécessaire.
    Bon courage...

  8. #8
    Expert éminent sénior
    Homme Profil pro
    Analyste/ Programmeur
    Inscrit en
    Juillet 2013
    Messages
    4 629
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Analyste/ Programmeur

    Informations forums :
    Inscription : Juillet 2013
    Messages : 4 629
    Points : 10 554
    Points
    10 554
    Par défaut
    Citation Envoyé par racine carrée Voir le message
    je pense qu'un moyen pourrait être de créer une liste chainées contenant des pointeurs vers des tableau (de type tableau dans ce code source), et ensuite de créer les fonctions qui vont bien pour récupérer une élément du tableau quand nécessaire.


    Est-ce que tu sais lire ? " j'aimerai récupérer des données données dans une tableau 2d"
    C'est quoi cette idée de l'enfer de coder 1 liste chaînée pour 1 matrice/ tableau 2D

  9. #9
    Membre régulier
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    210
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Avril 2007
    Messages : 210
    Points : 91
    Points
    91
    Par défaut
    Citation Envoyé par Bousk Voir le message
    Est-ce que tu comptes récupérer de très larges sets de données ?
    Si non, utilise mysql_store_result puis mysql_num_rows.
    J'ai du mal comprendre comment initialiser mon tableau alors que je ne connais la taille qu'après lecture de chacune des lignes de la requête.

    La solution serait de faire 2 fois la requête:
    - la 1er fois pour compter le nombre i et de j pour connaître la taille de tableau[i][j]
    - la 2ème fois pour remplir mon tableau
    Mais je pense que la mémoire qui va être allouée est trop grande: si "i" va jusque de 1 à 10 et que "j" varie entre 1 et 100 pour chaque "i" => alors la taille de mon tableau sera de 10 x 100 alors que dans les faits j'ai peut-être besoin d'une taille 9 x 1 (car le 9 "i" ne contiennent qu'une valeur) + 1x100 (car il y a un "i" qui contient 100 valeurs différentes).



    Je vois une autre solution en récupérant le nombre de ligne avec "mysql_num_rows" ce qui me donne la taille de mon tableau. Enfin la taille globale : si le résultat est par exemple 109 car 109 ligne, est ce que je peux initialiser mon tableau comme cela :
    Puis utiliser mon tableau comme suit :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    tableau[0][0]=1;
    tableau[1][0]=5;
    tableau[2][0]=6;
    tableau[3][0]=1;
    tableau[3][1]=0;
    tableau[3][2]=8;
    ...
    tableau[3][99]=7;
    tableau[4][0]=5;
    tableau[5][0]=6;
    ...
    tableau[9][0]=6;

  10. #10
    Expert éminent sénior
    Homme Profil pro
    Analyste/ Programmeur
    Inscrit en
    Juillet 2013
    Messages
    4 629
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Analyste/ Programmeur

    Informations forums :
    Inscription : Juillet 2013
    Messages : 4 629
    Points : 10 554
    Points
    10 554
    Par défaut
    Citation Envoyé par sebaaas Voir le message
    J'ai du mal comprendre comment initialiser mon tableau alors que je ne connais la taille qu'après lecture de chacune des lignes de la requête.
    Il faut utiliser l'allocation dynamique et savoir qu'1 tableau à X dimensions en C est juste un tableau contiguë ligne par ligne en mémoire - il faut aller voir les cours si tu n'y connais rien.
    En gros, array[i][j] == array[j + i * nb_columns]

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
        int* array /* = NULL */;
        size_t nb_rows, nb_columns;
     
    //  lecture nb_rows, nb_columns
     
        array = malloc(nb_rows * nb_columns * sizeof(int));
     
       if (array != NULL) {
           memset(array, 0, (nb_rows * nb_columns);
       } else {
    //     error
       }
    memset : documentation officielle en anglais
    calloc : documentation officielle en anglais

    Ensuite, cela va dépendre pour faire la copie des données : soit avec une boucle for soit avec la fonction memcpy (<- lien cplusplus.com en anglais)

    Et n'oublie le free (<- lien cplusplus.com en anglais) pour désallouer ton tableau

  11. #11
    Membre habitué Avatar de racine carrée
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2018
    Messages
    156
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 23
    Localisation : France, Maine et Loire (Pays de la Loire)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2018
    Messages : 156
    Points : 137
    Points
    137
    Par défaut
    C'est quoi cette idée de l'enfer de coder 1 liste chaînée pour 1 matrice/ tableau 2D
    Moi j'aurais pensé faire une liste chainées de pointeurs vers des listes chainées contenant des char[const int], ce qui aurait permis de créer une matrice (à 2d) dont les des deux dimensions peuvent varier. Il est vrai que l'allocation dynamique dont tu parles parait intéressante, mais j'ai juste une interrogation à ce propos: à chaque élément qu'on rajoute à la fin du tableau on utilise realloc() pour agrandir le tableau, et cette fonction est obligée décaller toute la zone mémoire plus loin s'il n'y a pas assez de place pour l'agrandir; donc si on rajoute un nombre important d'éléments on a beaucoup de chances que l'ensembles des éléments soit déplacé un grand nombre de fois, ce qui risque de diminuer les performances. Alors que le fait d'utiliser une liste chainées de pointeurs vers des listes chainées de char[const int] ne va jamais tous les éléments lors de l'ajout d'un élément, mais réservera juste une place en mémoire et actualisera un pointeur (après il est vrai que cette méthode est plus longues à programmer et semble un peu tordue, et a probablement des inconvénients que je n'ai pas vus...)

    Je vois une autre solution en récupérant le nombre de ligne avec "mysql_num_rows" ce qui me donne la taille de mon tableau. Enfin la taille globale : si le résultat est par exemple 109 car 109 ligne, est ce que je peux initialiser mon tableau comme cela :
    Attention la taille d'un tableau statique est un const int, ce qui fait que sa taille ne peut pas dépendre d'une variable du programme (si tu fixes à 109 ok, mais ça sera toujours 109). C'est pour ça qu'il faut utiliser de l'allocation dynamique.

  12. #12
    Expert éminent sénior
    Homme Profil pro
    Analyste/ Programmeur
    Inscrit en
    Juillet 2013
    Messages
    4 629
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Analyste/ Programmeur

    Informations forums :
    Inscription : Juillet 2013
    Messages : 4 629
    Points : 10 554
    Points
    10 554
    Par défaut
    Citation Envoyé par racine carrée Voir le message
    à chaque élément qu'on rajoute à la fin du tableau on utilise realloc() pour agrandir le tableau, et cette fonction est obligée décaller toute la zone mémoire plus loin s'il n'y a pas assez de place pour l'agrandir; donc si on rajoute un nombre important d'éléments on a beaucoup de chances que l'ensembles des éléments soit déplacé un grand nombre de fois, ce qui risque de diminuer les performances
    Déjà, c'est l'allocateur mémoire qui est "en dessous" qui gère cela - cet allocateur est spécifique à chaque système d'exploitation et on ne sait pas vraiment comment il fonctionne.
    Mais tu as raison plus on fait d'allocations et/ ou de grosses allocations, plus il faut s'attendre à des recopies.

    C'est pour cela qu'à chaque réallocation , on fait cela par chunk (X cases par X cases) - std::vector travaille comme cela et c'est ce que j'ai fait dans mon code que j'ai posté dans mon précédent message.
    Et donc, la difficulté c'est de calibrer ce X. Dans mon code, à la fin, on a un tableau de 326688 valeurs ... alloué 7 par 7 - Ce n'est pas terrible - mais dès fois, on ne connait pas la taille finale.


    Citation Envoyé par racine carrée Voir le message
    Moi j'aurais pensé faire une liste chainées de pointeurs vers des listes chainées contenant des char[const int], ce qui aurait permis de créer une matrice (à 2d) dont les des deux dimensions peuvent varier.
    la liste chaînée pour des POD (Plain Old Data, entiers et flottants sauf structures) il faut vraiment vraiment 1 besoin spécifique.
    Pourquoi ? parce comme 1 valeur a au plus la taille d'1 pointeur (<= 4 ou 8 octets), tu doubles la quantité mémoire. (chaque maillon contient 1 POD + 1 pointeur)

  13. #13
    Rédacteur/Modérateur


    Homme Profil pro
    Network game programmer
    Inscrit en
    Juin 2010
    Messages
    7 115
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : Canada

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 115
    Points : 32 963
    Points
    32 963
    Billets dans le blog
    4
    Par défaut
    Citation Envoyé par sebaaas Voir le message
    J'ai du mal comprendre comment initialiser mon tableau alors que je ne connais la taille qu'après lecture de chacune des lignes de la requête. ...
    Et si tu lisais la doc au lieu de faire au petit bonheur ?

    mysql_use_result permet d'itérer sans connaître le nombre de résultats et est utilisé quand ils sont très nombreux. Parce qu'avoir tout ça en mémoire peut être problématique.
    C'est pourtant on ne peut plus clair si tu lis le lien...
    You may not use mysql_data_seek(), mysql_row_seek(), mysql_row_tell(), mysql_num_rows(), or mysql_affected_rows() with a result returned from mysql_use_result(), nor may you issue other queries until mysql_use_result() has finished. (However, after you have fetched all the rows, mysql_num_rows() accurately returns the number of rows fetched.)
    mysql_store_result met tout en mémoire et permet d'utiliser mysql_num_rows.
    Idem, j'ai juste lu la doc disponible pour absolument tout le monde...
    After you have called mysql_store_result() and gotten back a result that is not a null pointer, you can call mysql_num_rows() to find out how many rows are in the result set.
    Maintenant faudrait voir si tu as vraiment besoin de stocker ces résultats, parce qu'itérer dessus est bien souvent suffisant.
    Mais si tu veux connaître le nombre de résultats, il ne faut pas utiliser mysql_use_result mais mysql_store_result.
    Pensez à consulter la FAQ ou les cours et tutoriels de la section C++.
    Un peu de programmation réseau ?
    Aucune aide via MP ne sera dispensée. Merci d'utiliser les forums prévus à cet effet.

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

Discussions similaires

  1. [MySQL] Importation d'un tableau Excel vers une base de données mysql
    Par Glork dans le forum PHP & Base de données
    Réponses: 5
    Dernier message: 25/07/2013, 21h32
  2. [JDBC]acces à une base de données mysql
    Par sehaba dans le forum JDBC
    Réponses: 13
    Dernier message: 07/12/2004, 00h39
  3. probleme construction base de donnes MySql...Help
    Par chakan dans le forum Requêtes
    Réponses: 7
    Dernier message: 21/07/2004, 11h27
  4. connection à base de donnée MYSQL
    Par zouzou_zaza dans le forum Bases de données
    Réponses: 11
    Dernier message: 04/07/2004, 12h31
  5. XML->Base de donnée Mysql
    Par lheureuxaurelie dans le forum XQUERY/SGBD
    Réponses: 4
    Dernier message: 10/03/2004, 23h47

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