2010-03-09 15 views
0

Je fais une calculatrice polynomiale et j'ai besoin d'aide pour progresser dans le code.Calculatrice polynomiale

Pour l'instant je n'ai fait que la classe polinom que je l'ai représentée sous la forme d'une liste chaînée avec des termes et quelques fonctions (lire et imprimer seulement les fonctions polynomiales pour l'instant).

Voici le programme principal qui, pour lire maintenant seulement un polynôme et imprime:

#include "polinom.h" 

int main() 

{ 

polinom P1; 
bool varStatus = false; 
char var = '\0', readStatus = '\0'; 

cout << "P1 = "; 
P1.read(readStatus, var, varStatus); // i don't need readStatus yet as i haven't implemented the reset and quit functions 

cout << "\n\nP = "; 
P1.print(var); 

getch(); 
return 0; 
} 

Et le fichier d'en-tête polinom.h:

#ifndef _polinom_h 
#define _polinom_h 

#include <iostream> 
#include <list> 
#include <cstdlib> 
#include <cctype> 
#include <cstdio> 
#include <conio.h> 


using namespace std; 

class polinom 
{ 
class term 
{ 
    public: 
     int coef; 
     int pow; 

     term() 
     { 
      coef = 1; 
      pow = 0; 
     }  
}; 

list<term> poly; 
list<term>::iterator i; 

public: 

    bool printable(char c) 
    { 

     return (
        ((int(c) > 42 && int(c) < 123) || isspace(c)) && int(c) != 44 && int(c) != 46 && int(c) != 47 && 
        int(c) != 58 && int(c) != 59 && 
        int(c) != 60 && int(c) != 61 && int(c) != 62 && int(c) != 63 && int(c) != 64 && int(c) != 65 && 
        int(c) != 91 && int(c) != 92 && int(c) != 93 && int(c) != 95 && int(c) != 96 
       ); 
    } 


    void read(char &readStatus, char &var, bool &varStatus) 
    { 

     term t; // term variable to push it into the list of terms 
     char c, lc, sign; // c = current char, lc = lastchar and sign the '+' or '-' sign before a coefficient 
     int coef, pow; //variables to pass the coef and power to term t 
     bool coefRead = false, powRead = false; //reading status of coef and power 

     while (c != '\r') { //we read characters until carriage return 
      c = getch(); // get the new imputed char 

      if (tolower(c) == 'r' || tolower(c) == 'q') { //if the user inputed r or q we reset the input or quit the program 
        readStatus = c; //pass current char value to readStatus so the program will know what to do next 
        return; //aborting the reading process 
      } 

      else 
      { 
       if (printable(c)) cout << c; //print on screen only the correct characters 

       if (!coefRead && !powRead) //we set term coef to the inputed value 
       {      
        if (isdigit(c)) { 
         if (isdigit(lc)) coef = coef * 10 + int(c); //if the last char was also a digit we multiply the last value of coef by 10 and add current char 
         else {          
          if (sign == '-') coef = -(int(c));//if the current coef has '-' before we set coef to it's negative value 
          else    coef = int(c); //this means a new term's coef is read 
        } 
        if (!isdigit(c) && isdigit(lc)) coefRead = true; //if the last char was a digit and we reached the var name we stop reading the coefficient 
       } 

       else if (coefRead && !powRead) //after coefficient is read we get the term's varname and power 
       { 
        if (isdigit(c)) { // just like in the case with coefficient we read the power until the current char is not a digit 
         if (isdigit(lc)) pow = pow * 10 + int(c); 
         else pow = int(c); 
        } 

        else if (isalpha(c) && isdigit(lc) && !varStatus) { //if the last char was a digit and the current not we reached the var name 
        var = c;           //also even though the variable is inputed more than once we save it only once 
        varStatus = true; //we mark the var name as read 
        } 
        else { 
         if (isdigit(lc)) powRead = true; 
        } 
       } 

      else { 
       if (c == '+' || c == '-') { // if a sign was inputed it means a new term is coming and we push the current term to the list and reset 
        t.coef = coef;   // coefRead and powRead so we can read another term 
        t.pow = pow; 
        poly.push_back(t); 
        sign = c; 
        coefRead = false; 
        powRead = false; 
       } 
      } 

      lc = c; // we save the last character 

      } 
     } 
    } 

    void print(char var) 
    { 
     for (i=poly.begin() ; i != poly.end(); i++) { //going through the entire list to retrieve the terms and print them 

      if (i == poly.end() - 1) { // if we reached the last term 
       if (*(i->pow == 0) //if the last term's power is 0 we print only it's coefficient 
        cout << *(i->coef); 
       else 
        cout << *(i->coef) << var << "^" << *(i->pow); //otherwise we print both 
      } 

      else { 
       if (*(i->coef > 0) //if the coef value is positive 
        cout << *(i->coef) << var << "^" << *(i->pow) << " + "; //we also add the '+' sign 
       else 
        cout << *(i->coef) << var << "^" << *(i->pow) << " - "; // otherwise we add '-' sign 
      } 
     } 
    } 

}; 


#endif      

EDIT

Tous compilez les erreurs sont maintenant corrigées grâce à JonH, mais la fonction de lecture ne fonctionne pas car les caractères d'entrée ne sont pas correctement insérés dans la liste. Je sais que c'est peut-être trivial pour vous les gars, mais ce serait bien si vous m'aidez.

Merci!

+1

pourquoi ai-je reçu -1 à ma question? – Vlad

+4

Parce que vous avez vomi votre code partout sur notre internet. –

+1

Veuillez envoyer des messages d'erreur * exact *, y compris le numéro de ligne. – abelenky

Répondre

1

Les erreurs de compilation a sûrement un numéro de ligne qui leur est associée dans le message d'erreur. Avez-vous essayé de regarder la ligne indiquée pour voir ce qui manque? Si cela ne vous aide pas, veuillez envoyer la sortie d'erreur complète du compilateur afin que nous puissions voir quelle est l'erreur.

+0

Ok, j'ai édité et posté les messages d'erreur complets – Vlad

+0

@Vlad - voir ma réponse ci-dessous vous manquiez 2-3 accolades, quand le code commence à ressembler à ceci il est correct de commenter après une accolade de fin 'if (blah) {//lots et beaucoup de code} // fin si ... c'est ok à faire' – JonH

+0

@JonH voir mon commentaire à votre réponse s'il vous plaît – Vlad

2

Votre problème fondamental est que vous avez écrit un tas de codes sans les tester pièce par pièce, sans y penser. Lorsque vous écrivez en tant que débutant, vous devriez essayer d'ajouter un petit peu à la fois et de vous assurer qu'il est compilé. Même en tant que programmeur avancé, la modularisation est une partie extrêmement importante du processus de conception et d'écriture de code.

Cela dit, voici quelques conseils sur votre code affiché en particulier:

  1. Votre fonction printable est laid comme le péché, et donc impossible de debug ou comprendre.
  2. Le nombre d'instructions imbriquées if indique des défauts de conception.
  3. Une parenthèse de fin manque sur votre instruction if (isdigit(c)).
  4. Déclarant (et en particulier l'initialisation) plusieurs variables sur la même ligne est mauvaise forme.
+0

Re: 1. Cette fonction est clairement juste de vérifier les codes ASCII pour déterminer si un caractère est imprimable ou pas. Il dit en gros que 'c' est entre' * 'et' ('(exclusif) ou est un espace et ne fait pas partie d'une liste finie de caractères à exclure.Il est moche, et mal écrit, et peut être amélioré de façon significative mais Je suis d'accord avec le reste de vos points – jason

+0

Je suis impressionné que vous ayez mémorisé la totalité de la table ASCII: Impossible était un mot fort, peut-être, mais quand votre code est obscurci par la traduction de 'char' s dans leurs valeurs 'int', et quand vous enchaînez une centaine de tests logiques, quelque chose de très mauvais pourrait facilement passer inaperçu.C'est ce que je voulais dire: –

+0

mémoriser les valeurs ASCII n'est pas difficile du tout – JonH

1

Il vous manque quelques accolades dans votre fonction de lecture.

Je refis ici:

void read(char &readStatus, char &var, bool &varStatus) 
{ 

    term t; // term variable to push it into the list of terms 
    char c, lc, sign; // c = current char, lc = lastchar and sign the '+' or '-' sign before a coefficient 
    int coef, pow; //variables to pass the coef and power to term t 
    bool coefRead = false, powRead = false; //reading status of coef and power 

    while (c != '\r') { //we read characters until carriage return 
     c = getch(); // get the new imputed char 

     if (tolower(c) == 'r' || tolower(c) == 'q') 
     { //if the user inputed r or q we reset the input or quit the program 
       readStatus = c; //pass current char value to readStatus so the program will know what to do next 
       return; //aborting the reading process 
     } 

     else 
     { 
      if (printable(c)) 
       cout << c; //print on screen only the correct characters 

      if (!coefRead && !powRead) //we set term coef to the inputed value 
      {      
       if (isdigit(c)) 
        { 
        if (isdigit(lc)) 
         coef = coef * 10 + int(c); //if the last char was also a digit we multiply the last value of coef by 10 and add current char 
        else 
         {          
         if (sign == '-') 
          coef = -(int(c));//if the current coef has '-' before we set coef to it's negative value 
         else    
          coef = int(c); //this means a new term's coef is read 
         } //end else 
        }//end if isdigit(c) 
       if (!isdigit(c) && isdigit(lc)) 
        coefRead = true; //if the last char was a digit and we reached the var name we stop reading the coefficient 
      } //end if 

      else if (coefRead && !powRead) //after coefficient is read we get the term's varname and power 
      { 
       if (isdigit(c)) 
        { // just like in the case with coefficient we read the power until the current char is not a digit 
        if (isdigit(lc)) 
         pow = pow * 10 + int(c); 
        else 
         pow = int(c); 
        } 

       else if (isalpha(c) && isdigit(lc) && !varStatus) 
        { //if the last char was a digit and the current not we reached the var name 
         var = c;           //also even though the variable is inputed more than once we save it only once 
          varStatus = true; //we mark the var name as read 
        } 
       else 
        { 
        if (isdigit(lc)) 
         powRead = true; 
        }  
      } //end else if 

     else 
      { 
      if (c == '+' || c == '-') 
       { // if a sign was inputed it means a new term is coming and we push the current term to the list and reset 
        t.coef = coef;   // coefRead and powRead so we can read another term 
        t.pow = pow; 
        poly.push_back(t); 
        sign = c; 
        coefRead = false; 
        powRead = false; 
       } 
       } 

     lc = c; // we save the last character 

     } //end else 
    } //end while 
} //end function 

EDIT

I également fixé la fonction d'impression:

void print(char var) 
    { 
     for (i=poly.begin() ; i != poly.end(); i++) { //going through the entire list to retrieve the terms and print them 

      if (i == poly.end()) { // if we reached the last term 
       if (i->pow == 0) //if the last term's power is 0 we print only it's coefficient 
        cout << i->coef; 
       else 
        cout << i->coef << var << "^" << i->pow; //otherwise we print both 
      } 

      else { 
       if (i->coef > 0) //if the coef value is positive 
        cout << i->coef << var << "^" << i->pow << " + "; //we also add the '+' sign 
       else 
        cout << i->coef << var << "^" << i->pow << " - "; // otherwise we add '-' sign 
      } 
     } 
    } 
+0

bien merci pour votre aide, mais maintenant il dit que l'utilisation de unary * est illégale et aussi aucune correspondance pour l'opérateur poly.end() - 1 – Vlad

+0

@Vlad ce sont des erreurs supplémentaires, cela efface seulement l'erreur sur les accolades. – JonH

+0

@vlad que vous appelez poly.end(), est-ce que ça existe? – JonH

10

J'ai trouvé des accolades de nombreux disparus et la fermeture parens tout au long de votre code . Après avoir passé plusieurs minutes à en fixer au moins 10, je pensais que vous seriez mieux servi si je vous aidais à apprendre à pêcher, plutôt que de vous donner du poisson pour le dîner de ce soir.

Votre code s'écrit comme un courant de conscience. Au fur et à mesure que vous construisez votre code, votre esprit se met à penser à d'autres choses que vous devez construire et à de nouvelles exigences introduites par ce que vous venez d'écrire. Quand vous pensez à ces choses, vous allez les écrire et revenir là où vous étiez. Avant de le savoir, vous avez écrit des centaines de lignes de code en sautant, en écrivant des morceaux ici et là. Le problème avec ceci est que vous ne pouvez pas continuer à jongler avec des sections de code de cette manière sans manquer de petits bits de syntaxe en cours de route.

Vous devriez adopter une approche plus itérative de l'écriture de code. Comment exactement vous faites cela viendra avec l'expérience, mais voici quelques conseils:

  1. Commencez par écraser une déclaration de classe avec quelques (de préférence 1) méthodes de base et les variables membres.
  2. Compile. Vous obtiendrez des erreurs d'éditeur de liens et autres, mais vous ne devriez pas avoir d'erreurs de syntaxe comme des parenthèses ou des points-virgules manquants. Fixe tout ce que tu trouves avant de continuer.
  3. Implémentez les méthodes/fonctions que vous venez de créer. Compiler & corriger les erreurs de non-éditeur de liens.
  4. En pensant aux exigences mineures ou dépendantes qui sont apparues au cours des étapes ci-dessus, écrivez des commentaires dans votre code, comme // TODO: Implement bool DoTheThing(int); mais ne les implémentez pas encore.
  5. Remontez à l'étape 1, en limitant autant que possible la portée de vos travaux. Ne jamais aller au-delà d'une étape de compilation sans une compilation propre.

Répétez jusqu'à ce que vous ayez tout implémenté. Vous pourriez compiler 50 fois ou plus pendant ce processus.

+2

Bonne réponse. Cela va à la racine du problème et suggère une solution à long terme. Vous pouvez voir déjà à partir d'une autre réponse que corriger spécifiquement les erreurs de compilation n'aide pas le demandeur, car alors il se heurte immédiatement à une autre erreur et n'a toujours aucune idée de ce qu'il faut faire. – indiv

+1

@indiv - Dire que ça n'aide pas n'a probablement pas raison, car cela a certainement aidé l'affiche. Vous pouvez toujours essayer d'aider et d'expliquer les choses comme je l'ai fait dans le code avec des commentaires. C'est pourquoi nous avons aussi des commentaires. – JonH