Partage
  • Partager sur Facebook
  • Partager sur Twitter

invalid types 'int[int]' for array subscript

    13 janvier 2019 à 19:49:04

    Ksass`Peuk a écrit:

    Il aurait déjà fallu créer des types précis pour chaque "niveau" de ton imbrication. Et par extension, une fonction pour chaque niveau.


    j'avoue ne pas bien comprendre

    Ksass`Peuk a écrit:

    Pour les trucs non-conventionnels de manipulation de la console, voir du côté de ncurses et les équivalents sur les différents OS.

    Je vais y jeter un coup d'œil

    je remets le code complet pour faire un compte rendu des modifs

    #include <iostream>
    #include <fstream>
    #include <string>
    #include <chrono>
    #include <cassert>
    #include <vector>
    #include <sstream>
    #include <cstdio>
    #include <windows.h>
    
    struct _brain{
        size_t nb_layers;
        std::vector<size_t> nb_neurons;
        std::vector< std::vector< std::vector<float> > > connections;
    };
    
    struct _chess_board{
        int board[8][8];
        bool turn;
        bool black_king_side_castle;
        bool black_queen_side_castle;
        bool white_king_side_castle;
        bool white_queen_side_castle;
        int column_en_passant;
    };
    
    const int NB_NEURONS_IN_FIRST_COLUMN = 10;
    
    char getCh()
    {
      HANDLE hStdin = GetStdHandle (STD_INPUT_HANDLE);
      INPUT_RECORD irInputRecord;
      DWORD dwEventsRead;
      CHAR cChar;
    
      while(ReadConsoleInputA (hStdin, &irInputRecord, 1, &dwEventsRead)) /* Read key press */
        if (irInputRecord.EventType == KEY_EVENT
    	&&irInputRecord.Event.KeyEvent.wVirtualKeyCode != VK_SHIFT
    	&&irInputRecord.Event.KeyEvent.wVirtualKeyCode != VK_MENU
    	&&irInputRecord.Event.KeyEvent.wVirtualKeyCode != VK_CONTROL)
        {
          cChar = irInputRecord.Event.KeyEvent.uChar.AsciiChar;
    	ReadConsoleInputA (hStdin, &irInputRecord , 1, &dwEventsRead); /* Read key release */
    	return cChar;
        }
      return EOF;
    }
    
    bool is_file_empty(std::string file_name)
    {
        bool file_empty;
        std::ifstream brain_file(file_name.c_str(), std::ios::in);
        if(brain_file)
            file_empty = false;
        else
            file_empty = true;
        brain_file.close();
        return file_empty;
    }
    
    std::string chooseBrain()
    {
        std::string file_name;
        bool file_empty;
        int brain_number;
        do
        {
            std::cout << "Choose the brain you wanna load: ";
            std::cin >> brain_number;
            file_name = "brains/brain_file.txt";
                file_name.insert(17, std::to_string(brain_number));
            file_empty = is_file_empty(file_name);
        }
        while(file_empty);
        return file_name;
    }
    
    void loadNbLayers(std::ifstream& xbrain_file, _brain xbrain)
    {
        xbrain_file >> xbrain.nb_layers;
    }
    
    void loadNbNeurons(std::ifstream& xbrain_file, _brain xbrain)
    {
        size_t temp_nb_neurons;
        for(size_t cnt = 0; cnt < xbrain.nb_layers; cnt++)
        {
            xbrain_file >> temp_nb_neurons;
            xbrain.nb_neurons.push_back(temp_nb_neurons);
        }
    }
    
    void loadConnections(std::ifstream& xbrain_file, _brain xbrain)
    {
        float temp_connection;
        for(size_t cnt1 = 0; cnt1 < xbrain.nb_layers - 1; cnt1++)
        {
            xbrain.connections.push_back(std::vector< std::vector<float> >());
            for(size_t cnt2 = 0; cnt2 < xbrain.nb_neurons[cnt1]; cnt2++)
            {
                xbrain.connections[cnt1].push_back(std::vector<float>());
                for(size_t cnt3 = 0; cnt3 < xbrain.nb_neurons[cnt1 + 1]; cnt3++)
                {
                    xbrain_file >> temp_connection;
                    xbrain.connections[cnt1][cnt2].push_back(temp_connection);
                }
            }
        }
    }
    
    void loadBrain(_brain xbrain, std::string xfile_name)
    {
        std::ifstream brain_file(xfile_name.c_str(), std::ios::in);
        if(brain_file)
        {
            loadNbLayers(brain_file, xbrain);
            loadNbNeurons(brain_file, xbrain);
            loadConnections(brain_file, xbrain);
            brain_file.close();
        }
        else
            std::cerr << "Impossible d'ouvrir le fichier !" << std::endl;
    }
    
    void chooseAndLoadBrain(_brain xbrain)
    {
        std::string file_name = chooseBrain();
        loadBrain(xbrain, file_name);
    }
    
    std::string emptyFileFinder()
    {
        unsigned int index = 0;
        bool file_empty;
        std::string file_name;
        do
        {
            file_name = "brains/brain_file.txt";
            file_name.insert(17, std::to_string(index));
            file_empty = is_file_empty(file_name);
            index++;
        }
        while(!file_empty);
        return file_name;
    }
    
    void saveNbLayers(std::ofstream& xbrain_file, _brain xbrain)
    {
        xbrain_file << xbrain.nb_layers << std::endl << std::endl;
    }
    
    void saveNbNeurons(std::ofstream& xbrain_file, _brain xbrain)
    {
        for(size_t cnt1 = 0; cnt1 < xbrain.nb_layers; cnt1++)
            xbrain_file << xbrain.nb_neurons[cnt1] << ' ';
        xbrain_file << std::endl << std::endl;
    }
    
    void saveConnections(std::ofstream& xbrain_file, _brain xbrain)
    {
        for(size_t cnt1 = 0; cnt1 < xbrain.nb_layers - 1; cnt1++)
        {
            for(size_t cnt2 = 0; cnt2 < xbrain.nb_neurons[(unsigned int)cnt1]; cnt2++)
            {
                for(size_t cnt3 = 0; cnt3 < xbrain.nb_neurons[(unsigned int)cnt1 + 1]; cnt3++)
                    xbrain_file << xbrain.connections[(unsigned int)cnt1][(unsigned int)cnt2][(unsigned int)cnt3] << ' ';
                xbrain_file << std::endl;
            }
        xbrain_file << std::endl;
        }
    }
    
    void saveBrain(_brain xbrain)
    {
        std::string file_name = emptyFileFinder();
        std::ofstream brain_file(file_name.c_str(), std::ios::out | std::ios::trunc);
        if(brain_file)
        {
            saveNbLayers(brain_file, xbrain);
            saveNbNeurons(brain_file, xbrain);
            saveConnections(brain_file, xbrain);
            brain_file.close();
        }
        else
            std::cerr << "Impossible d'ouvrir le fichier !" << std::endl;
    }
    
    void dimensionningBrain(_brain& xbrain)
    {
        size_t temp_nb_neurons;
        std::cout << "Number of layers:";
        std::cin >> xbrain.nb_layers;
        xbrain.nb_layers = xbrain.nb_layers + 2;
        xbrain.nb_neurons.push_back(NB_NEURONS_IN_FIRST_COLUMN);
        for(size_t cnt1 = 1; cnt1 < xbrain.nb_layers - 1; cnt1++)
        {
            std::cout << "Number of node in layer " << cnt1 << ": ";
            std::cin >> temp_nb_neurons;
            xbrain.nb_neurons.push_back(temp_nb_neurons);
        }
        xbrain.nb_neurons.push_back(1);
    }
    
    void generateRandomConnectionValues(_brain& xbrain)
    {
        for(size_t cnt1 = 0; cnt1 < xbrain.nb_layers - 1; cnt1++)
        {
            xbrain.connections.push_back(std::vector< std::vector<float> >());
            for(size_t cnt2 = 0; cnt2 < xbrain.nb_neurons[cnt1]; cnt2++)
            {
                xbrain.connections[cnt1].push_back(std::vector<float>());
                for(size_t cnt3 = 0; cnt3 < xbrain.nb_neurons[cnt1 + 1]; cnt3++)
                    xbrain.connections[cnt1][cnt2].push_back(((rand()/(RAND_MAX)) * 2.) - 1.);
            }
        }
    }
    
    void randomBrainGenerator(_brain& xbrain)
    {
        dimensionningBrain(xbrain);
        generateRandomConnectionValues(xbrain);
    }
    
    void generateBrain(_brain xbrain)
    {
        randomBrainGenerator(xbrain);
        saveBrain(xbrain);
    }
    
    void selectBrainCreationMethod(_brain xbrain)
    {
        char choice;
        std::cout << "[L]oad brain_file" << std::endl << "[G]enerate a random brain_file" << std::endl << "[Q]uit program" << std::endl;
        do
        {
            choice = getCh();
            switch(choice)
            {
                case 'l':
                    chooseAndLoadBrain(xbrain);
                break;
                case 'g':
                    generateBrain(xbrain);
                break;
                default:
                break;
            }
        }while(choice != 'l' && choice != 'g' && choice != 'q');
    }
    
    void selectAction(/*_brain xbrain*/)
    {
        char choice;
        std::cout << "[P]lay against AI" << std::endl << "[E]volve AI" << "[R]ate a custom chessboard" << std::endl << "[Q]uit program" << std::endl;
        do
        {
            choice = getCh();
            switch(choice)
            {
                case 'p':
                    //playAgainstAI(brain);
                break;
                case 'e':
                    //evolution(brain);
                break;
                case 'r':
                    //rateChessBoard(brain);
                default:
                break;
            }
        }while(choice != 'p' && choice != 'e' && choice != 'r' && choice != 'q');
    }
    
    
    int main()
    {
        srand (static_cast <unsigned> (time(0)));
        _brain brain;
        selectBrainCreationMethod(brain);
        selectAction(/*brain*/);
        return 0;
    }
    



    et aussi la igne 277 me donne une erreur de pointeur nul !

    -
    Edité par ThéoSarda1 13 janvier 2019 à 20:11:05

    • Partager sur Facebook
    • Partager sur Twitter
      13 janvier 2019 à 20:45:20

      ThéoSarda1 a écrit:

      Ksass`Peuk a écrit:

      Il aurait déjà fallu créer des types précis pour chaque "niveau" de ton imbrication. Et par extension, une fonction pour chaque niveau.

      j'avoue ne pas bien comprendre

      Plutôt que :

      std::vector<std::vector<std::vector<float>>> machin ;

      Et :

      for( ...
        for( ...
          for( ...

      Faire :

      using un_nom_pertinent = std::vector<float> ;
      using un_autre_nom_pertinent = std::vector<un_nom_pertinent> ;
      using un_dernier_nom = std::vector<un_autre_nom_pertinent> ;
      
      // (voir même de nouvelles structures selon les besoins)
      
      un_dernier_nom machin ;
      

      Et :

      void un_nom_de_fonction(un_nom_pertinent const&){
        for(...
          //traitement
      }
      void un_autre_nom_de_fonction(un_autre_nom_pertinent const& truc){
        for(...
          un_nom_de_fonction(truc[n]);
      }
      void un_dernier_nom_de_fonction(un_dernier_nom_pertinent const& machin){
        for(...
          un_autre_nom_de_fonction(machin[n]);
      }

      Ce qui permet de découper les traitements et de mieux savoir de quoi on parle à chaque étape.

      ThéoSarda1 a écrit:

      et aussi la igne 277 me donne une erreur de pointeur nul !

      La ligne 277 de ce code ne fait rien de mal. Par contre pour l'aléatoire, il est préférable d'utiliser les générateurs du header random.

      • Partager sur Facebook
      • Partager sur Twitter

      Posez vos questions ou discutez informatique, sur le Discord NaN | Tuto : Preuve de programmes C

        13 janvier 2019 à 20:59:05

        Super ! Par contre que veut dire using dans ce cas ?
        • Partager sur Facebook
        • Partager sur Twitter
          13 janvier 2019 à 21:00:41

          C'est une sorte d'alias pour donner un sens a un type.

          Tres pratique dans ton cas par exemple.

          • Partager sur Facebook
          • Partager sur Twitter

          Architecte logiciel - Software craftsmanship convaincu.

            13 janvier 2019 à 21:01:04

            ThéoSarda1 a écrit:

            Super ! Par contre que veut dire using dans ce cas ?

            Ca crée un "alias" de type. A savoir un nouveau nom pour le type qui suit. C'est comme typedef, sauf que typedef il ne faut pas l'utiliser.

            • Partager sur Facebook
            • Partager sur Twitter

            Posez vos questions ou discutez informatique, sur le Discord NaN | Tuto : Preuve de programmes C

              13 janvier 2019 à 22:07:58

              okay et dans le cas de 'using namespace std;' ?
              • Partager sur Facebook
              • Partager sur Twitter
                13 janvier 2019 à 22:23:19

                Plutot que faire des alias de types, tu peux meme (surtout) creer des classes pour chaque niveau, en lui donnant une semantique claire et des contrats précis. (Layer, Neurone, Connection)
                • Partager sur Facebook
                • Partager sur Twitter
                  13 janvier 2019 à 22:59:48

                  tu pourrais me donner un exemple ? je n'ai jamais touché aux classes
                  • Partager sur Facebook
                  • Partager sur Twitter
                    13 janvier 2019 à 23:05:01

                    Ben non. Si tu n'as jamais touché aux classes, ca sert a rien que je te donne 2-3 lignes de code. Prends un cours.
                    • Partager sur Facebook
                    • Partager sur Twitter
                      14 janvier 2019 à 1:46:13

                      using _output_neuron = std::vector<float> ;
                      using _input_neuron = std::vector<_output_neuron> ;
                      using _connection_layer = std::vector<_input_neuron> ;
                      
                      struct _brain{
                          size_t nb_layers;
                          std::vector<size_t> nb_neurons;
                          _connection_layer connections;
                      };
                      void loadConnectionsForOneInputNeuron(std::ifstream& xbrain_file, _output_neuron& connection, size_t xnb_output_neurons)
                      {
                        float temp_connection;
                        for(size_t cnt = 0; cnt < xnb_output_neurons; cnt++)
                          {
                              xbrain_file >> temp_connection;
                              connection.push_back(temp_connection);
                          }
                      }
                      
                      void loadConnectionsForOneGridOfConnections(std::ifstream& xbrain_file, _input_neuron& input_related_connections, size_t xnb_input_neurons, size_t xnb_output_neurons)
                      {
                          for(size_t cnt = 0; cnt < xnb_input_neurons; cnt++)
                          {
                              input_related_connections.push_back(std::vector<float>());
                              loadConnectionsForOneInputNeuron(xbrain_file, input_related_connections[cnt], xnb_output_neurons);
                          }
                      }
                      
                      void loadConnections(std::ifstream& xbrain_file, _brain xbrain)
                      {
                          for(size_t cnt = 0; cnt < xbrain.nb_layers - 1; cnt++)
                          {
                              loadConnectionsForOneGridOfConnections(xbrain_file, xbrain.connections[cnt], xbrain.nb_neurons[cnt], xbrain.nb_neurons[cnt + 1]);
                              xbrain.connections.push_back(std::vector< std::vector<float> >());
                          }
                      }


                      et voilà !

                      cependant goût personnel je préfère mes vieux for imbriqués

                      et de toute façon je suis pratiquement sûr que ce n'est toujours pas bon ?

                      -
                      Edité par ThéoSarda1 14 janvier 2019 à 1:53:36

                      • Partager sur Facebook
                      • Partager sur Twitter
                        14 janvier 2019 à 5:08:27

                        ThéoSarda1 a écrit:

                        "les 'for' sont des 'if' !" ça m'éclaire sur pas mal de messages mais je ne vois pas comment je peux parcourir un vecteur à trois dimension sans ces boucles. Et puis dans ce cas il n'y a pas 2 chemins je pense c'est le même chemin emprunté un certain nombre de fois (même si c'est peut-être très mal dit)

                        les boucles, quelles quelle soient, effectuent d'office un test...

                        C'est un test du genre de

                        si (la condition d'entrée dans la boucle est vérifiée)
                            je reprend au début de la boucle
                        sinon
                            je vais à la première instruction qui suit

                        je renote les problèmes pour faire le point:

                          A: les typedef c'est mal --> comment je m'en défait ?

                           B: les if (et donc les boucles imbriquées) c'est mal --> comment je parcours ce vecteur 3d sans ?

                           C:conio.h c'est mal --> j'ai un getch dans mes menus, y a-t-il une alternative ?

                        A: Quand tu écrit du code C++, tu ne mets simplement pas de typedef... le code
                        struct Machin{
                            /* les différentes données membres */
                        };
                        déclare déjà le nom Machin comme étant un type de donnée (du moins, en C++).  Il n'y a donc aucune raison de vouloir définir une type de donnée à la C, qui prend une forme proche de
                        typedef struct{
                            /* les différentes données
                        } Machin; // voici le nom, qui arrive APRES la définition
                                  // de la struture

                        B: Tu as plusieurs solutions.

                        La "plus efficace" est de partir du principe que

                        Chaque nom (groupe nominal) dans ton analyse des besoins doit être représenté sous la forme d'une donnée ou d'un type de donnée dans ton code

                        Chaque verbe (groupe verbal) dans ton analyse des besoins doit être représenté sous la forme d'une fonction dans ton code

                        Et de rajouter un soupçon d'encapsulation dans l'histoire, car chaque type de donnée devrait être considéré comme un fournisseur de services:

                        Un neurone, par exemple, cela peut obéir à "certains ordres", et cela peut répondre à "certaines questions",et le cerveau peut obéir aux ordres "crée plus de neurones", "crée une liaison entre tel neurone à tel autre" et "évalue telle liaison".

                        Grâce à cela, tu obtiendras des "notions élémentaires", qui veilleront à ne s'occuper que d'une seule chose bien particulière.  Et, du coup, les trois dimensions de ton tableau devraient être "réparties" dans les différentes notions que tu auras créées.

                        Et les services rendus par ces différentes notions pourront se contenter de boucler  sur une des dimensions de ton tableau, quitte à faire appel à "une fonction particulière" d'une autre notion pour ... boucler sur les autres dimensions de ton tableau.

                        L'autre solution consiste à "linéariser" tes tableaux à dimensions multiples, mais elle ne peut être envisagée que quand on a affaire à des "matrice pleines" .

                        En gros, il s'agit de se dire que, si on a une matrice à N dimensions, que la première dimension doit contenir X élément, que la deuxième doit en contenir Y , que la troisème doit en contenir Z et que la Nieme doit en contenir Y' (sous entendu: nous connaissons exactement le nombre d'éléments que nous trouverons dans chacune des dimensions), notre but est en fait de pouvoir représenter un  nombre d'éléments correspondant à X*Y*Z...*Z' et donc de créer, non pas un tableau à N dimensions, mais bel et bien un tableau à une seule dimension, qui contient l'ensemble des éléments auxquels nous voulons avoir accès.

                        Après, il y a le problème de l'accès aux éléments.  Pour cela, on utilise une formule "relativement simple" qui, pour deux dimensions, revient à indice_de_l_element_rechreche = ligne * NOMBRE_COLONNE + colonne.

                        pour trois dimensions, cela revient donc à quelque chose comme  indice_de_l_element_recherche = ((X * NOMBRE_EN_Y)+Y)*NOMBRE_EN_Z + Z.

                        ATTENTION : la linéarisation semble impossible dans ton cas, je n'en ai parlé que par soucis d'être complet ;)

                        C: tu veux extraire un caractère de l'entrée standard.  Que penserais tu de

                        char choice;
                        std::cin>>choice;
                        /* la suite */

                        Je fais volontairement simple ici ;)

                        • Partager sur Facebook
                        • Partager sur Twitter
                        Ce qui se conçoit bien s'énonce clairement. Et les mots pour le dire viennent aisément.Mon nouveau livre : Coder efficacement - Bonnes pratiques et erreurs  à éviter (en C++)Avant de faire ce que tu ne pourras défaire, penses à tout ce que tu ne pourras plus faire une fois que tu l'auras fait
                          14 janvier 2019 à 9:37:21

                          ThéoSarda1 a écrit:

                          cependant goût personnel je préfère mes vieux for imbriqués

                          C'est pas une histoire de goûts personnels. Statistiquement, les développeurs font plus d'erreurs quand les fonctions sont plus longues. D'autant plus quand on imbrique des boucles. Donc si on veut faire moins d'erreurs, on fait du code moins compliqué.

                          Après, on peut quand même se pencher sur ton code. Qu'est ce que tu penses de :

                          using neuron = std::vector<float> ;
                          using layer = std::vector<neuron> ;
                          using brain = std::vector<layer> ;
                           
                          using file_error = std::runtime_error ;
                          
                          std::size_t loadNbLayers(std::ifstream& brain_file){
                            // Note: il faut vérifier les erreurs
                            std::size_t number ;
                            brain_file >> number ;
                            return number ;
                          }
                          
                          std::vector<std::size_t> loadNbNeurons(std::ifstream& brain_file, std::size_t nb_layers){
                            std::vector<std::size_t> neurons_by_layer (nb_layers) ;
                            for(std::size_t& nb_neurons: neurons_by_layer){
                              // Note: il faut vérifier les erreurs
                              brain_file >> nb_neurons ;
                            }
                            return neurons_by_layer ;
                          }
                          
                          neuron loadNeuron(std::ifstream& brain_file, std::size_t nb_neurons)
                          {
                            neuron connections(nb_neurons) ;
                            for(float& connection : connections){
                              // Note : manque traitement des erreurs
                              brain_file >> connection;
                            }
                            return connections ;
                          }
                           
                          layer loadLayer(std::ifstream& brain_file, size_t nb_input_neurons, size_t nb_output_neurons)
                          {
                            layer input_related_connections ;
                            for(size_t cnt = 0; cnt < nb_input_neurons; cnt++){
                              auto output_neuron = loadNeuron(brain_file, nb_output_neurons) ;
                              input_related_connections.push_back(output_neuron) ;
                            }
                            return input_related_connections ;
                          }
                          
                          brain build_brain_from_file(std::ifstream& brain_file, std::vector<std::size_t> neurons_by_layer){
                            brain b ;
                            for(size_t i = 0 ; i < neurons_by_layer.size() - 1 ; ++i){
                              size_t input = neurons_by_layer[i] ;
                              size_t output = neurons_by_layer[i+1] ;
                              b.push_back(loadLayer(brain_file, input, output)) ;
                            }
                            return b ;
                          }
                          
                          brain loadBrain(std::string file_name){
                            std::ifstream brain_file(file_name);
                            if(! brain_file) throw file_error { "unable to load file: " + file_name } ;
                          
                            auto nb_layers = loadNbLayers(brain_file);
                            auto neurons_by_layer = loadNbNeurons(brain_file, nb_layers);
                            return build_brain_from_file(brain_file, neurons_by_layer) ;
                          }

                          Ce code de chargement fait la même chose que le tien, en revanche, il évite de manipuler des références et de faire des effets de bord qui rendent le code plus compliqué à comprendre.

                          (Note : dans l'espace de nom global, ne nomme pas des éléments de ton programme avec un "_" en préfixe, c'est réservé aux compilos/bibliothèques standard).

                          -
                          Edité par Ksass`Peuk 14 janvier 2019 à 11:34:34

                          • Partager sur Facebook
                          • Partager sur Twitter

                          Posez vos questions ou discutez informatique, sur le Discord NaN | Tuto : Preuve de programmes C

                            14 janvier 2019 à 12:21:10

                            ThéoSarda1 a écrit:

                            char getCh()
                            {
                              HANDLE hStdin = GetStdHandle (STD_INPUT_HANDLE);
                              INPUT_RECORD irInputRecord;
                              DWORD dwEventsRead;
                              CHAR cChar;
                            
                              while(ReadConsoleInputA (hStdin, &irInputRecord, 1, &dwEventsRead)) /* Read key press */
                                if (irInputRecord.EventType == KEY_EVENT
                            	&&irInputRecord.Event.KeyEvent.wVirtualKeyCode != VK_SHIFT
                            	&&irInputRecord.Event.KeyEvent.wVirtualKeyCode != VK_MENU
                            	&&irInputRecord.Event.KeyEvent.wVirtualKeyCode != VK_CONTROL)
                                {
                                  cChar = irInputRecord.Event.KeyEvent.uChar.AsciiChar;
                            	ReadConsoleInputA (hStdin, &irInputRecord , 1, &dwEventsRead); /* Read key release */
                            	return cChar;
                                }
                              return EOF;
                            }

                            D'habitude on encourage à faire des recherches pour aboutir aux fonctionnalités désirées, mais le je croit qu'une intervention devient nécessaire:
                            L'équivalent de getch() est std::cin.get();

                            PS: S'il s'agit de faire une pause en fin de programme pour éviter que la console ne se ferme, revoit la configuration ton IDE.

                            • Partager sur Facebook
                            • Partager sur Twitter
                              14 janvier 2019 à 12:55:16

                              Deedolith a écrit:

                              L'équivalent de getch() est std::cin.get();

                              Hum non. std::cin nécessite que le flux d'entrée soit "validé" par l'utilisateur. La fonction getch attend juste un appui sur la touche pour la renvoyer. Cela dit, comme je l'ai dit, voir du côté de ncurses et équivalents.

                              • Partager sur Facebook
                              • Partager sur Twitter

                              Posez vos questions ou discutez informatique, sur le Discord NaN | Tuto : Preuve de programmes C

                              invalid types 'int[int]' for array subscript

                              × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
                              × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
                              • Editeur
                              • Markdown