no match for 'operator>>' in 'std::cin >>

Signaler
Messages postés
16
Date d'inscription
dimanche 26 avril 2009
Statut
Membre
Dernière intervention
21 mai 2010
-
Messages postés
3839
Date d'inscription
dimanche 12 décembre 2004
Statut
Modérateur
Dernière intervention
15 avril 2021
-
Bonjour,
Mon problème est le suivant :
lors ce que je compile mon programme C++ sous codeblocks ou visual c++ 2008 express j'ai cette erreur là:
In member function void Banque::interfaceCreerClient()
" no match for 'operator>>' in 'std::cin >> nomClient

voici le code :
void Banque::interfaceCreerClient() {
cout << endl;
cout << "Entrez le nom du nouveau client :" << endl;
String nomClient;
cin >> nomClient;

if(isClientExiste(nomClient)) {
cout << "Un client du meme nom existe deja." << endl;
interfaceCreerClient();
} else {
creerClient(nomClient);
cout << "Client cree." << endl;
interfaceAdministrateur();
}

J'ai aussi declarer un "using namespace std;" pour ne plus marquer std::cin ou std::cout
Merci d'avance pour votre aide.

16 réponses

Messages postés
3839
Date d'inscription
dimanche 12 décembre 2004
Statut
Modérateur
Dernière intervention
15 avril 2021
120
J'ai aussi declarer un "using namespace std;" pour ne plus marquer std::cin ou std::cout

Beurk ! A éviter. Mieux vaut écrire std::, ça t'éviteras bien des problèmes plus tard. Si tu veux vraiment écrire cout au lieu de std::cout, préfère : "using std::cout;". Faire sauter tout les namespaces, ce n'est pas très judicieux...

Sinon, pour ton erreur, il te dit qu'il ne sait pas comment remplir la variable nomClient, car celle-ci n'est pas de type string, mais est de type String. Donc il va chercher la surcharge de l'opérateur >> dans la classe personnalisé String.
Est-ce une faute de frappe, ou as-tu vraiment créer une classe String ?
Messages postés
16
Date d'inscription
dimanche 26 avril 2009
Statut
Membre
Dernière intervention
21 mai 2010

bonjour,

Merci pour votre aide, et ce n'est pas une faute de frappe, mais j'ai vraiment créer une classe String.
Avant j'avais pleins d'erreurs qui disait la même chose pour operator << quand je faisais des cout, et avec le déclaration de unsing namespace std ca ma résolut le problème mais la...

la voila ma classe String:
#include <string.h>
#include

#include "String.h"


String::String ( char* newStrRep)
{
int taille = strlen(newStrRep);
strRep = new char[taille];
strcpy(strRep, newStrRep);
}

String::String ( const String& newString )
{
int taille = strlen(newString.strRep);
strRep = new char[taille];
strcpy(strRep, newString.strRep);
}

String::~String ()
{
delete[] strRep;
//delete this;
}

String& String::operator = ( const String& newString)
{
delete[] strRep;
int taille = strlen(newString.strRep);
strRep = new char[taille];
strcpy(strRep, newString.strRep);
return *this;
}

void String::print () const
{
std::cout << strRep;
}

int String::operator == ( const String& newString)
{
if( strlen(strRep) != strlen(newString.strRep) )
{
return 0;
} else
{
for( int i = 0 ; i < strlen(strRep) ; i++)
{
if( strRep[i] != newString.strRep[i] )
{
return 0;
}
}
return 1;
}
}

String String::operator + (String & newString )
{
int newLength = strlen(strRep) + strlen(newString.strRep);
char* newStrRep = new char[newLength];
for(int index = 0 ; index < strlen(strRep) ; index++ )
{
newStrRep[index] = strRep[index];
}
for(int index = 0 ; index < strlen(newString.strRep) ; index++ )
{
newStrRep[strlen(strRep) + index] = newString.strRep[index];
}
return String(newStrRep);
}

char & String::operator [] ( int index)
{
return strRep[index];
}

String::operator char* () const
{
return strRep;
}

void String::setString ( char * newStrRep)
{
delete[] strRep;
int taille = strlen(newStrRep);
strRep = new char[taille];
strcpy(strRep, newStrRep);
}

Si vous pouvez m'aider s'il vous plait.
Messages postés
3839
Date d'inscription
dimanche 12 décembre 2004
Statut
Modérateur
Dernière intervention
15 avril 2021
120
Ce n'est pas compliqué, tu dois redéfinir operator<< dans ta classe "String", sinon std::cout ne sait pas comment intéragir avec. Ce n'est pas parce que tu as nommé ta classe "String" que l'intéraction est automatique.
C'est exactement comme si tu faisais:

Toto t;
std::cout << t << std::endl;

Il y a incompréhension de la part du compilateur.

De même, pour intéragir avec std::cin, il te faut redéfinir operator>>, un peu comme tu l'as fait pour operator[] et operator+.
Messages postés
16
Date d'inscription
dimanche 26 avril 2009
Statut
Membre
Dernière intervention
21 mai 2010

Ah d'accord, alors pour cout je fais :(par exemple je sais si c'est exactement ça)

ostream &operator<<( ostream &out, String &chaine )
{
out << chaine.getChaine();
return out;
}

avec
char *String::getChaine()
{
return chaine;
}


Mais pour cin je ne vois pas trop comment faire.
Messages postés
3839
Date d'inscription
dimanche 12 décembre 2004
Statut
Modérateur
Dernière intervention
15 avril 2021
120
Un petit exemple de redéfinition de flux pour std::cout et std::cin, qui devrait répondre à ta question:

#include 

class T
{
  friend std::istream& operator>> (std::istream& i, T& t);
  friend std::ostream& operator<< (std::ostream& o, const T& t);

public:
  T () {}
private:
  std::string s_;
};

std::istream& operator>> (std::istream& i, T& t)
{
  i >> t.s_;
  return i;
}

std::ostream& operator<< (std::ostream& o, const T& t)
{
  o << t.s_;
  return o;
}

int main()
{
  T t;

  std::cout << "Entrez t: ";
  std::cin >> t;
  std::cout << t << std::endl;

  return 0;
}
Messages postés
16
Date d'inscription
dimanche 26 avril 2009
Statut
Membre
Dernière intervention
21 mai 2010

Merci, et au niveau du T.h il faut mettre quoi comme fonction public ?
Messages postés
16
Date d'inscription
dimanche 26 avril 2009
Statut
Membre
Dernière intervention
21 mai 2010

Merci, et au niveau du T.h il faut mettre quoi comme fonction public ?
Je parle des opérateur >> et << .
Messages postés
16
Date d'inscription
dimanche 26 avril 2009
Statut
Membre
Dernière intervention
21 mai 2010

C'est bon merci à vous. maintenant je compile j'ai plus d'erreur.
Messages postés
16
Date d'inscription
dimanche 26 avril 2009
Statut
Membre
Dernière intervention
21 mai 2010

Maintenant lors de la compilation du programme j'ai l'erreur suivante, sachant que j'ai fais ce que vous m'avez demandé de faire.

>> binaire : aucun opérateur trouvé qui accepte un opérande de partie droite de type 'std::string' ou il n'existe pas de conversion acceptable
Messages postés
3839
Date d'inscription
dimanche 12 décembre 2004
Statut
Modérateur
Dernière intervention
15 avril 2021
120

>> binaire : aucun opérateur trouvé qui accepte un opérande de partie droite de type 'std::string' ou il n'existe pas de conversion acceptable

Il faut que je vois ce qui provoque l'erreur pour pouvoir t'aider. Peux-tu joindre un extrait de code qui déclenche ceci ?
Messages postés
16
Date d'inscription
dimanche 26 avril 2009
Statut
Membre
Dernière intervention
21 mai 2010

oui voila le code : String.cpp

#include "stdafx.h"
#include <string.h>
#include 
#include "String.h"

using namespace std;

String::String ( char* newStrRep)
{
  int taille = strlen(newStrRep); 
  strRep = new char[taille]; 
  strcpy(strRep, newStrRep);
}

String::String ( const String& newString ) 
{
  int taille = strlen(newString.strRep);
  strRep = new char[taille];
  strcpy(strRep, newString.strRep);
}

String::~String ()
{
  delete[] strRep;
  //delete this;
}

String& String::operator = ( const String& newString)
{
  delete[] strRep;
  int taille = strlen(newString.strRep);
  strRep = new char[taille];
  strcpy(strRep, newString.strRep);
  return *this;
}

std::istream& operator>> (std::istream& in, String& newString)
{
  in >> newString.s_;
  return in;
}

std::ostream& operator<< (std::ostream& out, const String& newString)
{
  out << newString.s_;
  return out;
}


void String::print () const
{
  cout << strRep;
}

int String::operator == ( const String& newString)
{
  if( strlen(strRep) != strlen(newString.strRep) )
    {
      return 0;
    } else
      {
        for( int i = 0 ; i < strlen(strRep) ; i++)
  {
            if( strRep[i] != newString.strRep[i] )
      {
                return 0;
      }
  }
        return 1;
      }
}



char & String::operator [] ( int index)
{
  return strRep[index];
}

String::operator char* () const
{
  return strRep;
}


et le String.h

#ifndef STRING_H
#define STRING_H

#include <string.h>
#include 
using namespace std;

class String
{
    friend std::istream& operator>> (std::istream& in, String& );
    friend std::ostream& operator<< (std::ostream& out, const String& );


private:
  char* strRep;
  std::string s_;

public:
  String ( char* = "" );       // Parametre de valeur par defaut ""
  String ( const String& ); 
  ~String ();
  String& operator= ( const String& );
  void print () const;
  int operator == ( const String& );
  String operator + (String & );
  char & operator [] ( int );
  operator char* () const;
  void setString ( char * );
  
};

#else
class String;

#endif 



l'erreur c'est ca :

c:\documents and settings\cissine\mes documents\visual studio 2008\projects\projetbanque\projetbanque\string.cpp(39) : error C2679: '>>' binaire : aucun opérateur trouvé qui accepte un opérande de partie droite de type 'std::string' (ou il n'existe pas de conversion acceptable)
e:\program files\microsoft visual studio 9.0\vc\include\istream(1144): peut être 'std::basic_istream<_Elem,_Traits> &std::operator >><std::char_traits<char>>(std::basic_istream<_Elem,_Traits> &,signed char *)'
Messages postés
3839
Date d'inscription
dimanche 12 décembre 2004
Statut
Modérateur
Dernière intervention
15 avril 2021
120
Je t'ai corrigé quelques petites erreurs qui trainaient.
En plus de cela, j'ai un peu "proprisé" ton code. Pourquoi appelé ta classe "String" avec un S majuscule ? Tu as tout à fait le droit de l'appeler "string" si tu le met dans un namespace à toi. C'est d'ailleurs la raison pour laquelle on a créée ce méchanisme. Par exemple au lieu de std::string, tu peux avoir my::string.
J'ai viré les using namespace std;, qui en plus d'être moche, sont dangereux quand mis dans un header (en effet, quelqu'un qui inclue ton fichier se fait sauter tout ses espaces de noms, alors qu'il n'a rien demandé: bonjour les conflits !).

Enfin, j'ai modifié quelques petits trucs (par exemple, en cas d'affectation ou de comparaison, je test si l'objet lui même n'essaie pas de s'affecter ou de se comparer lui même).

J'ai aussi corrigé quelques warning (notamment la comparaison entre nombres signés et non signés, et la tentative de passage de "" dans un char* au lieu d'un const char*).

Ceci, fonctionne donc parfaitement chez moi:

string.hh:
#ifndef STRING_HH_
# define STRING_HH_

# include 

namespace my
{
  class string
  {
    friend std::istream& operator>> (std::istream& in, string& s);
    friend std::ostream& operator<< (std::ostream& out, const string& s);

  private:
    char* strRep;

  public:
    string(const char* newStrRep = "");
    string(const string& newstring);
    ~string();
    string& operator=(const string& newstring);
    void print(std::ostream& out) const;
    int operator== (const string& newstring);
    string operator+ (string & newstring);
    char& operator[] (int index);
    operator char*() const;
    void setstring(const char* newStrRep);
  };
}
#endif /* !STRING_HH_ */


string.cc:
#include "string.hh"
#include <string.h>
#include 

namespace my
{
  string::string(const char* newStrRep)
  {
    int taille = strlen(newStrRep);
    strRep = new char[taille];
    strcpy(strRep, newStrRep);
  }

  string::string(const string& newString)
  {
    int taille = strlen(newString.strRep);
    strRep = new char[taille];
    strcpy(strRep, newString.strRep);
  }

  string::~string()
  {
    delete[] strRep;
  }

  string& string::operator=(const string& newString)
  {
    if (this == &newString)
      return *this;
    delete[] strRep;
    int taille = strlen(newString.strRep);
    strRep = new char[taille];
    strcpy(strRep, newString.strRep);
    return *this;
  }

  void string::print(std::ostream& out) const
  {
    out << strRep;
  }

  int string::operator==(const string& newString)
  {
    if (this == &newString)
      return 1;

    int size = strlen(strRep);
    for (int i = 0 ; i < size; ++i)
      if (strRep[i] != newString.strRep[i])
return 0;

    return 1;
  }

  char& string::operator[](int index)
  {
    return strRep[index];
  }

  string::operator char*() const
  {
    return strRep;
  }

  std::istream& operator>>(std::istream& in, string& newString)
  {
    in >> newString.strRep;
    return in;
  }

  std::ostream& operator<<(std::ostream& out, const string& newString)
  {
    out << newString.strRep;
    return out;
  }
}


main.cc:
#include "string.hh"
#include 

int main()
{
  std::string words = "Entrez phrase: ";
  my::string s1;
  my::string s2;

  s1 = s1;
  std::cout << words << std::endl;
  std::cin >> s1;
  std::cout << words << std::endl;
  std::cin >> s2;
  std::cout << s1 << std::endl;
  std::cout << s2 << std::endl;
  std::cout << (s1 == s2) << std::endl;
  s1 = s2;
  std::cout << (s1 == s2) << std::endl;


  return 0;
}
Messages postés
16
Date d'inscription
dimanche 26 avril 2009
Statut
Membre
Dernière intervention
21 mai 2010

bonjour,
Maintenant vu que j'ai pas que la classe String dans mon projet, j'ai aussi quelques classes 'Banque, Client, Opération ...' lorsque j'exécute mon projet, j'ai zéro erreur, mais un message s'affiche qui dis :

"Windows a déclenché un point d'arrêt dans ProjetBanque.exe"

aussi j'ai ça : impossible d'ouvrir le fichier en-tête pré-compilé Debug/ProjetBanque.pch
Messages postés
3839
Date d'inscription
dimanche 12 décembre 2004
Statut
Modérateur
Dernière intervention
15 avril 2021
120
impossible d'ouvrir le fichier en-tête pré-compilé Debug/ProjetBanque.pch

Je ne suis pas sous Windows, donc j'ai un peu du mal à voir ce qui ne vas pas, la-dessus.

Windows a déclenché un point d'arrêt dans ProjetBanque.exe

Soit tu as effectivement posé un breakpoint, auxquels cas il faut voir avec ton IDE si tu peux les retirer, soit tu as une erreur d'exécution, qu'il te faut alors corriger.

Passe ton projet dans un debugger, et regarde ce qui se passe.
Messages postés
16
Date d'inscription
dimanche 26 avril 2009
Statut
Membre
Dernière intervention
21 mai 2010

Alors quand j'ai passé mon projet dans un debugger en mode pas à pas et j'ai découvert ca :

quand je fais Banque maBanque="banque de test" , il y a un souci au niveau de ma classe String ici:

String::String (const char* newStrRep)
{
int taille = strlen(newStrRep);
--> strRep = new char[taille];
strcpy(strRep, newStrRep);
}
qui me met comme erreur, il n'y a pas de code source disponible pour l'emplacement en cours..
ensuite le point d'arrêt est à ce niveau là :

String& String::operator = ( const String& newString)
{
if(this == &newString)

return *this;
--> delete[] strRep;
int taille = strlen(newString.strRep);
strRep = new char[taille];
strcpy(strRep, newString.strRep);
return *this;
}

voila mon main
#include "stdafx.h"

#include <cstdlib>
#include 
#include "Banque.h"

using namespace std;

int main()
{
cout << "\n--- Projet gestion de banque ---\n";

Banque maBanque="Banque de France";

maBanque.creerClient("Toto");
maBanque.creerCompte("Toto", 1);
maBanque.creerCompte("Toto", 2);
maBanque.crediterCompte(1, 500);
maBanque.cloturerOperations();
maBanque.afficherInterface();
    
cout << "\n--- Fin du projet -------------\n";

    return EXIT_SUCCESS;
}
"

et ma classe banque
#include "banque.h"

#include 
#include <string>



Banque::Banque(String newNom)
{
nom = newNom;
clients = vector<Client*>(0);
comptes = vector<CompteBancaire*>(0);
operationsCourantes = vector<Operation*>(0);
continuer = false;
}

Banque::~Banque ()
{
  clients.~vector();
  comptes.~vector();
  operationsCourantes.~vector();
}
Messages postés
3839
Date d'inscription
dimanche 12 décembre 2004
Statut
Modérateur
Dernière intervention
15 avril 2021
120
clients = vector<Client*>(0);
comptes = vector<CompteBancaire*>(0);
operationsCourantes = vector<Operation*>(0);

Beurk !!!
Déclare dans Banque.h:
private:
std::vector<Client*> clients;
std::vector<CompteBancaire*> comptes;
std::vector<Operation*> operationsCourantes;

Et retire les 3 lignes que j'ai cité, ainsi que ceci:
clients.~vector();
comptes.~vector();
operationsCourantes.~vector();


Et hop, une copie pour rien !
Banque::Banque(String newNom)

Met plutôt:
Banque::Banque(const String& newNom)


using namespace std;

Toujours la même remarque. A éviter.


strRep = new char[taille];

Il manque la place pour le 0 terminal, donc plutôt mettre:
strRep = new char[taille + 1];