Partage
  • Partager sur Facebook
  • Partager sur Twitter

Erreur à partir d'une certaine ligne

    11 avril 2021 à 18:31:55

    Bonjour,

    Depuis que j'ai intégré les lignes à la fin concernant la fonction "invnumgb", il y a une erreur qui est détectée, et l'exécution ne fonctionne normalement que jusqu'aux lignes avant ces lignes-là. Je n'arrive pas à voir où le problème ? Est-ce l'utilisation de "cout", ou bien celle des pointeurs ? Ou autre chose ? 

    Voici le code du main :

    #include "Header.h"
    
    #include <iostream>
    #include<vector>
    using namespace std;
    
    
    int main()
    {
        cout << "Hello World!\n";
        double a; int N; double b; int M;
        cout << "Entrez la borne supérieure selon x du domaine d'étude : \n ";
        cin >> a;
        cout << "\n Entrez le nombre d'intervalles souhaité selon x : \n";
        cin >> N;
        cout << "Entrez la borne supérieure selon y du domaine d'étude : \n ";
        cin >> M;
        cout << "\n Entrez le nombre d'intervalles souhaité selon y : \n";
        cin >> M;
        vector<double> subdivision = unifdiv(a, N);
        affiche_vecteur(subdivision); cout << "\n \n";
        
        int *i; int *j;
        cout << "la numérotation globale du noeud de coordonnées (i=";
        cin >> *i;
        cout << ", j=";
        cin >> *j;
        cout << ") est ";
        int s = numgb(N, M, *i, *j);
        cout << s ;
    
        int sp;
        cout << "la numérotation locale du noeud ";
        cin >> sp;
        invnumgb(N, M, sp, *i, *j);
        cout << "(" << *i << " ," << *j << ")";
      
     
        system("pause>0");
    
    }

    Et le code des fonctions

    #include "Header.h"
    
    #include <iostream>
    #include<vector>
    using namespace std;
    
    vector<double> unifdiv(double a, int N) {
    
    	vector<double> subdiv(N + 1, 0);
    
    	double x = 0;
    
    	double pas = a / (N + 1);
    
    	for (int i = 0; i <= N; i++) {
    		subdiv[i] = x;
    		x += pas;
    	}
    
    	return(subdiv);
    }
    	
    void affiche_vecteur(vector<double> v) {
    	
    	int n = v.size();
    	
    	cout << "[";
    	for (int i = 0; i < n; i++) {
    		cout << v[i] << " ";
    	}
    	cout << "]";
    
    }
    
    int numgb(int N, int M, int &i, int &j) {
    
    	if ((i > N) || (j > M)) {
    		cout << "les indices i ou j n'appartiennent pas un maillage";
    		exit(0);
    	};
    
    	int s = (N + 1) * j + i;
    	return(s);
    }
    
    void invnumgb(int N, int M, int s, int &i, int &j) {
    	
    	if (s > (N + 1) * (M + 1) - 1) {
    		cout << "numéro global incorrect";
    		exit(0);
    	}
    
    	i = s % (N + 1);
    	j = s/(N+1);
    	return(i, j);
    }
    

    Et le fichier d'en-tête

    #ifndef HEADER_H
    #define HEADER_H
    #endif
    
    #include <iostream>
    #include<vector>
    
    std::vector<double> unifdiv(double a, int N);
    void affiche_vecteur(std::vector<double> v);
    int numgb(int N, int M, int i, int j);
    void invnumgb(in

    J'écris ma réponse ici, car le site m'empêche de publier un nouveau message, il m'a identifié comme spam (?).

    Merci pour vos réponses. Je n'ai pas beaucoup de liberté pour les notations car je dois suivre celles de mon énoncé. Vous verrez ci-dessous les remarques que j'ai réussi à prendre en compte. Pour le moment, le problème d'exécution a au moins été résolu.

    #ifndef HEADER_H
    #define HEADER_H
    
    
    	#include <iostream>
    	#include<vector>
    
    	std::vector<double> unifdiv(double a, int N);
    	void affiche_vecteur(std::vector<double> v);
    	int numgb(int N, int M, int i, int j);
    	void invnumgb(int N, int M, int s, int *i, int *j);
    	
    
    #endif
    #include "Header.h"
    
    #include <iostream>
    #include<vector>
    using namespace std;
    
    vector<double> unifdiv(double a, int N) {
    
    	vector<double> subdiv(N + 1, 0);
    
    	double x = 0;
    
    	double pas = a / (N + 1);
    
    	for (int i = 0; i <= N; i++) {
    		subdiv[i] = x;
    		x += pas;
    	}
    
    	return(subdiv);
    }
    	
    void affiche_vecteur(vector<double> v) {
    	
    	int n = v.size();
    	
    	cout << "[";
    	for (int i = 0; i < n; i++) {
    		cout << v[i] << " ";
    	}
    	cout << "]";
    
    }
    
    int numgb(int N, int M, int i, int j) {
    
    	if ((i > N) || (j > M)) {
    		cout << "les indices i ou j n'appartiennent pas un maillage";
    		exit(0);
    	};
    
    	int s = (N + 1) * j + i;
    	return(s);
    }
    
    void invnumgb(int N, int M, int s, int *i, int *j) {
    	
    	if (s > (N + 1) * (M + 1) - 1) {
    		cout << "numéro global incorrect";
    		exit(0);
    	}
    
    	int i_ = s % (N + 1);
    	i = &i_;
    	int j_ = s / (N + 1);
    	j = &j_;
    
    }
    
    #include "Header.h"
    
    #include <iostream>
    #include<vector>
    using namespace std;
    
    
    int main()
    {
        cout << "Hello World!\n";
        double a; int N; double b; int M;
        cout << "Entrez la borne supérieure selon x du domaine d'étude : \n ";
        cin >> a;
        cout << "\n Entrez le nombre d'intervalles souhaité selon x : \n";
        cin >> N;
        cout << "Entrez la borne supérieure selon y du domaine d'étude : \n ";
        cin >> M;
        cout << "\n Entrez le nombre d'intervalles souhaité selon y : \n";
        cin >> M;
        vector<double> subdivision = unifdiv(a, N);
        affiche_vecteur(subdivision); cout << "\n \n";
        
        int *i = NULL ; int *j = NULL;
        cout << "la numérotation globale du noeud de coordonnées (i=";
        int i_; cin >> i_; i = &i_;
        cout << ", j=";
        int j_; cin >> j_; j = &j_;
        cout << ") est ";
        int s = numgb(N, M, *i, *j);
        cout << s ;
    
        int s2;
        cout << "la numérotation locale du noeud ";
        cin >> s2;
        invnumgb(N, M, s2, i, j);
        cout << "(" << *i << " ," << *j << ")";
      
     
        system("pause>0");
    
    }
    

    -
    Edité par ApprentiCpp 12 avril 2021 à 22:40:02

    • Partager sur Facebook
    • Partager sur Twitter
      11 avril 2021 à 19:13:39

      Salut, je commence par dire que le cours C++ d'OpenClassrooms est déconseillé en raison des mauvaises pratiques qu'il enseigne (fais une recherche sur le forum, tu trouveras de nombreuses remarques négatives), et ton code laisse penser que tu l'as suivi.

      Il n'y a normalement aucune raison que cout fasse planter ton programme, mais les pointeurs si (initialise les à nullptr, ou encore mieux, n'en utilises pas, et dans les cas où ils te sont nécessaires, va voir du côté de unique_ptr).

      Rassure-moi, tu as mal écrit le code du header dans ton message, parce que là il manque la liste des arguments, la parenthèse et le point-virgule.

      Il y a un truc bizarre dans ta fonction invnumgb, elle est déclarée void mais retourne une valeur (godbolt ne compile pas avec GCC 10.2 std=c++20).

      Autres remarques :

      Dans numgb, tu prend deux entiers en référence alors que tu ne les modifies pas, laisse-les par copie (un int c'est tout petit)

      Nommes tes variables convenablement

      return n'est pas une fonction, les parenthèses sont inutiles

      un vector prend de la place, passe le par référence constante 

      Les include guards (ifndef define endif) ne servent a rien car tu déclares tes fonctions en dehors du define-endif, donc aucune protection contre les inclusions multiples 

      Tu pourrais remplacer affiche_vecteur par une surcharge de l'opérateur << (en gardant ta sémantique) :

      template<typename ValueType>
      std::ostream& operator<<(std::ostream& stream, const std::vector<ValueType>& vector) {
          stream << '[';
          std::for_each(vector.cbegin(), vector.cend(), [] (const ValueType& value) { stream << value << ' '; });
          return stream << ']';
      }



      -
      Edité par Chi_Iroh 11 avril 2021 à 20:22:26

      • Partager sur Facebook
      • Partager sur Twitter
        11 avril 2021 à 19:25:49

        i, et j ne sont jamais alloués et initialisés, vous modifiez donc des zones mémoires complètement aléatoirement donc comportement complètement indéterminé.

        Comme l'indique @totosayen_cpp, il faut reprendre votre programme depuis le début (apprentissage du langage compris) car rien ne va dans votre programme.

        • Partager sur Facebook
        • Partager sur Twitter
        Je recherche un CDI/CDD/mission freelance comme Architecte Logiciel/ Expert Technique sur technologies Microsoft.
          12 avril 2021 à 10:21:18

          J'ai essayé (tant bien que mal) de réécrire un peu mieux le code si ça peut t'aider :

          // header.hpp
          
          #pragma once
          
          // ou
          // #ifndef HEADER_HPP
          // #define HEADER_HPP
          
          #include <iosfwd>
          #include <vector>
          
          
          std::vector<double> unifdiv(double maxX, unsigned nIntervalsX);
          
          std::ostream& operator<<(std::ostream& stream, const std::vector<double>& vector);
          
          int numgb(unsigned nIntervalsX, unsigned nIntervalsY, int coordsNodeI, int coordsNodeJ);
          
          std::pair<int, int> invnumgb(int nIntervalsX, int nIntervalsY, int coordsNodeNumbering, int coordsNodeI, int coordsNodeJ);
          
          void portablePause(bool displayMsg = true);
          
          // #endif
          
          // Source.cpp
          
          #include <iostream>
          
          #ifdef _WIN32
          #define NOMINMAX // Windows.h définit des macros min et max qui viendront produire des erreurs de compilation (si tu utilises std::max, std::numeric_limits<>::max etc..)
          #include <Windows.h>
          #endif
          int main() {
          
          #ifdef _WIN32
          	// problèmes de caractères spéciaux dans la console sous Windows
          	SetConsoleOutputCP(1252); // pour afficher
          	// SetConsoleCP(1252); pour récupérer depuis l'input (cin & cie)
          #endif
          
          	std::cout << "Hello World !" << std::endl;	// évite \n, endl force l'affichage
          
          	double maxX{ 0. };
          	std::cout << "Borne supérieure selon x du domaine d'étude (flottant) :" << std::endl;
          	std::cin >> maxX;
          
          	unsigned nIntervalsX{ 0u };	// traduction ici : https://www.wordreference.com/fren/intervalle
          	std::cout << std::endl << "Nombre d'intervalles souhaité selon x (naturel) :" << std::endl;
          	std::cin >> nIntervalsX;
          
          	double maxY{ 0. };
          	std::cout << "Borne supérieure selon y du domaine d'étude (flottant) :" << std::endl;
          	std::cin >> maxY;
          
          	unsigned nIntervalsY{ 0u };
          	std::cout << std::endl << "Nombre d'intervalles souhaité selon y (naturel) :" << std::endl;
          	std::cin >> nIntervalsY;
          
          	std::cout << unifdiv(maxX, nIntervalsX) << std::endl << std::endl; // subdivision
          
          	int coordsNodeI{ 0 };
          	std::cout << "La numérotation du noeud de coordonnées (i = "; // cohérent de ne pas mettre de endl
          	std::cin >> coordsNodeI;
          
          	int coordsNodeJ{ 0 };
          	std::cout << ", j = ";
          	std::cin >> coordsNodeJ;
          
          	const int coordsNodeNumbering{ numgb(nIntervalsX, nIntervalsY, coordsNodeI, coordsNodeJ) };
          	std::cout << ") est " << coordsNodeNumbering << std::endl;
          
          	std::cout << "La numérotation locale du noeud ";
          	int globalNodeNum{ 0 };	// peut être un unsigned ?
          	std::cin >> globalNodeNum;
          
          	const auto localNodeNumbering{ invnumgb(nIntervalsX, nIntervalsY, coordsNodeNumbering, coordsNodeI, coordsNodeJ) };
          	std::cout << std::endl << '(' << localNodeNumbering.first << ", " << localNodeNumbering.second << ')' << std::endl;
          
          	portablePause();
          
          	return 0; // ou EXIT_SUCCESS, comme tu veux c'est pareil
          }
          
          #include <cassert>
          
          std::vector<double> unifdiv(double maxX, unsigned nIntervalsX) {
          	nIntervalsX++; // pour éviter le +1 à chaque utilisation
          
          	std::vector<double> subdivision{};
          	subdivision.reserve(nIntervalsX);
          	// pas obligé de faire l'initilisation / remplissage comme moi, mais je trouve ça plus lisible comme ceci
          
          	const double step{ maxX / nIntervalsX };
          	double valueToInsert{ -step };
          
          	for (std::size_t index{ 0u }; index < nIntervalsX; index++) {
          		subdivision.push_back(valueToInsert += step);
          	}
          
          	return subdivision;
          }
          
          #include <algorithm>
          
          std::ostream& operator<<(std::ostream& stream, const std::vector<double>& vector) {
          	stream << '[';
          	std::for_each(vector.cbegin(), vector.cend(), [] (double value) {stream << value << ' ';});
          	return stream << ']';
          }
          
          #include <string>
          
          int numgb(unsigned nIntervalsX, unsigned nIntervalsY, int coordsNodeI, int coordsNodeJ) {
          	if (coordsNodeI > nIntervalsX || coordsNodeJ > nIntervalsY) {
          		const std::string errorMsg{ "Les indices de i (" + std::to_string(coordsNodeI) + ") ou de j (" + std::to_string(coordsNodeJ) + ") n'appartiennent pas à un maillage !" };
          		assert(!errorMsg.c_str()); // assert vient du C, donc traite des const char*
          	}
          	return (nIntervalsX + 1u) * coordsNodeJ + coordsNodeI;
          }
          
          std::pair<int, int> invnumgb(int nIntervalsX, int nIntervalsY, int coordsNodeNumbering, int coordsNodeI, int coordsNodeJ) {
          	if (coordsNodeNumbering > (nIntervalsX + 1u) * (nIntervalsY + 1u) - 1u) {
          		const std::string errorMsg{"Numéro global (" + std::to_string(coordsNodeNumbering) + ") incorrect !"};
          		assert(!errorMsg.c_str());
          	}
          	return { coordsNodeNumbering % (nIntervalsX + 1u), coordsNodeNumbering / (nIntervalsX + 1u) };
          }
          
          #include <limits>
          
          void portablePause(bool displayMsg) {
          	if (displayMsg) {
          		std::cout << "Appuyer sur une touche pour continuer..." << std::endl;
          	}
          	std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
          }




          -
          Edité par Chi_Iroh 12 avril 2021 à 16:11:43

          • Partager sur Facebook
          • Partager sur Twitter
            13 avril 2021 à 0:30:00

            @toto:
            Y'a du mieux.
            Les includes en plein milieu du code ..... bof.
            std::for_each est un peut obsolète maintenant qu'on a la boucle for ... each.
            Et utilise la deduction de type automatique, c'est plus clair:

            std::string myString{ "abcdefghijklmnop" };
            for(auto letter: myString)
                std::cout << letter;


            On préfère que l'OP se corrige lui même, poster une solution "clef en main" n'a aucun intérêt pédagogique, à part copier / coller.

            system("pause>0"); c'est une ineptie (même si tu écrits une version portable), si tu veux que que l'invite de commande ne se ferme pas à la fin de l'exécution, c'est dans les options de ton IDE que cela se passe.

            -
            Edité par Deedolith 13 avril 2021 à 0:36:57

            • Partager sur Facebook
            • Partager sur Twitter
              13 avril 2021 à 9:12:02

              @Deedolith merci pour tes conseils. Pour les includes, j'ai du confondre avec le faut qu'il faut en inclure le moins possible dans les headers, jai vu ça sur un sujet.
              Pour la boucle, c'est vrai que j'ai hésité à la mettre, mais je me suis dit algorithm c'est mieux ? Donc en fait, on n'a plus de raisons de s'en servir ?
              Et pour la pause, j'avais vu ça dans un sujet ou le PO avait fait une pause que pour Windows avec system, et un intervenant avait proposé une solution portable.
              EDIT : pour la boucle je suis bête, j'avais bien vu que sur cppreference elle utilisait les itérateurs comme pour for_each

              -
              Edité par Chi_Iroh 13 avril 2021 à 9:46:08

              • Partager sur Facebook
              • Partager sur Twitter

              Erreur à partir d'une certaine ligne

              × 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