Zeichen oder Zahl?



  • Was soll ich machen wenn ich nicht weiss ob ein Eingabewert eine Zahl (float) oder eine Zeichen ist?

    Ich arbeite gerade an einem Taschenrechner und da soll man auch mit Klammern rechnen können.
    Der erste Wert könnte eine Klammer sein oder eine Gleitkommazahl sein.

    Bitte helft mir!



  • Dann wertest du einfach den ASCII Code des Zeichens aus. Danach kannst du deine Zeichen klassifizieren...

    http://de.wikipedia.org/wiki/Ascii



  • Kannst du das bitte näher erläutern?
    Was ist wenn eine ascii zahl einer anderen Zahl gleicht??
    Ausserdem ist wenn ich alles in char habe, keine Zahl über 255 möglich und mein Rechner sollte doch etwas mehr können.



  • Als Erstes, erläutere bitte mal genauer was du damit meinst:

    muhi schrieb:

    Was soll ich machen wenn ich nicht weiss ob ein Eingabewert eine Zahl (float) oder eine Zeichen ist?

    Das ist nämlich nicht gerade eine eindeutige Problembeschreibung. Am Besten mit Codeschnipseln von deinem Projekt.

    Wie meine ich das? Tja, also:

    Jemand gibt ein Zeichen in die Tastatur ein. Du schaust nach dem ASCII Code des Zeichens:

    48 <= zeichen <= 57 --> Das ist eine Ziffer.

    Um Zeilen á la "34 * 21 - (8 / 2) * 0.5" richtig einzulesen bräuchtest du schon einen richtigen Parser. Aber ich glaube nicht, dass du dir das antun willst. Wenn du einen "einfachen" Rechner schreiben willst, musst du damit leben, dass der Nutzer nur eine fest-definierte Form der Gleichung eingeben kann. zB:

    Argument1 Operand1 Argument2 Operand2 Argument3

    Dann kannst du stumpf entweder Operanden oder Argumente einlesen.



  • Übrigens würde ich nicht jedes Zeichen einzeln einlesen, sondern mir eine komplette Eingabezeile auf einmal vornehmen:

    char* pos;//aktuelle Position in der Eingabe
    
    switch(*pos)
    {
    case '(':
      pos++;
      //bearbeite (
      break;
    case ')':
      pos++;
      //bearbeite )
      break;
    case ' ':
      pos++;
      break;
    case '+':case '-':case '*':case '/':
      pos++;
      //bearbeite Operator
      break;
    default:
      {
        char* npos;
        double val;
        val=strtod(pos,&npos);
        if(pos==npos)
          error("das ist keine Zahl");
        else
          pos=npos;
        //bearbeite Zahl
        break;
      }
    }
    


  • CStoll schrieb:

    Übrigens würde ich nicht jedes Zeichen einzeln einlesen, sondern mir eine komplette Eingabezeile auf einmal vornehmen

    Jupp, dass is natürlich effizienter. Obwohl ... bei einem Tippfehler müsste der Anwender dann den ganzen Spaß nochmal eingeben.



  • DarthZiu schrieb:

    Jupp, dass is natürlich effizienter. Obwohl ... bei einem Tippfehler müsste der Anwender dann den ganzen Spaß nochmal eingeben.

    Da die Konsole buffered ist und die Auswertung eh erst nach der Eingabetaste überhaupt beginnt ➡ Wurst 😉

    Für History und Commandline-Editing muss man sowieso lowlevel in der Konsole arbeiten, das geht mit Standardmitteln nicht.



  • Gut, bin bis eben davon ausgegangen, dass man nach jeder Eingabe (Operand, Argumemt) Enter drückt und die Sachen einliest. Aber das is natürlich nicht gerade benutzerfreundlich.

    Ich sollte ins Bett gehen ... 😕



  • Das hier ist ein Code-Schnipsel:

    #include <stdio.h>
    #include <math.h>
    
    int main ()
    
    {
    float a, b, c,d , e=1,extra,xneu,xalt,i;
    char answere,hilf[5] ;
    
    printf ("Wollen sie eine Spezial-Operation ausführen?\n");
    printf ("(y/n)") ; /*10*/
    
    scanf ("%c", &answere) ;
    
    /* hier nicht vergessen ne switch oder if anweisung zu machen*/ 
    
    Anfang: /* scanne alle elemente ein */
    
    scanf ("%f", &a) ;  /*20*/
    scanf ("%c", &hilf[2]);
    
    if (hilf[2]!='w') /* Wenn w eingescannt wird, wird gleich die wurzel gezogen, es ist kein weiterer einscann-vorgang nötig.*/
    {
    scanf ("%f%c", &b, &hilf[3]);  
    }	
    
    if (hilf[2]=='+') {c=a+b, printf ("%7.3f\n", c) ;} 
    if((hilf[2]=='-')&&(a>=b) ) {c=a-b ,printf ("%7.3f\n", c); }  /*30*/
    if ((hilf[2]=='-') &&(a<b) ) { c=b-a, extra=-c, printf ("%7.3f\n", extra) ;} 
    if ((hilf[2]=='*') ) {c=a*b , printf ("%7.3f\n", c) ; }
    if ((hilf[2]=='/')&& (b!=0)) {c=a/b, printf ("%7.3f\n", c) ; }
    if ((hilf[2]=='/') &&(b==0)) {printf ("Diese Operation ist nicht definiert\n");} ;
    

    Wie oben beschrieben hätte ich gerne, dass es egal is ob an erster Stelle eine Zahl oder ein Zeichen eingegeben wird.

    Eine Frage: Was passiert wenn ein Zeichen in zb. eine long variable eingelesen wird? Oder umgekehrt?

    Thx im Voraus



  • Ui ist das statisch.

    Also wenn du damit Klammern rechnen willst, dann solltest du deine Vorgehensweise überdenken. Das wird so nicht klappen.

    Grob gibt es IMHO zwei Ansätze für die Eingabe der "Formel":

    1. Der Nutzer wird aufgefordert jeden Operanden und jede Operation einzugeben und diese Eingabe mit Enter zu bestätigen. Das ist zwar recht statisch, da du vorgeben musst, wieviele Sachen eingegeben werden können und klappt auch nicht mit Klammer-Rechnung, dafür ist das Einlesen der Eingabe recht einfach.

    2. Der Nutzer gibt eine komplette Zeile ein, drückt dann Enter. Du suchst in dieser Zeichenkette dann nach Operanden und Operationen. Das ist extrem flexibel, klappt mit Klammer-Rechnung, dafür ist es nicht so ohne. Das kommt einem Parser schon recht nahe.

    Dein Code-Schnipsel sieht so aus, als ob du beide Verfahren vermischst. Wie gut sind denn deine Programmier-Kenntnisse (specially in ANSI C)?

    BTW:
    Ich finde es ziemlich heftig, dass vor allem beim Studium immerwieder diese Taschenrechneraufgabe dran ist. Meiner Meinung nach ist es ein ziemlich schwieriges und aufwändiges Verfahren die Eingabe zu verarbeiten. Der einzig komplett richtige Weg der mir da einfallen würde, wäre die Eingabe durch einen Zustandsautomaten zu jagen, der alles verifiziert.
    Oder lieg ich da falsch?



  • Lol, leider noch nicht so umfassend, ich habe vor ein paar Monaten begonnen.
    Ich hab mir überlegt einen Parser (hab vorher ned gwusst dass das so heisst.)zu machen.

    Also eine abwechselnde Sequenz wo die Zahlen in ein float array und die operanden in ein char array eingelesen werden.
    Das wollt ich ihn eine for-schleife einbauen und i inkrementieren.

    Ich habe lange überlegt wie ichs anders machen könnte und habe auch was auf Papier, das Problem ist, da gehts am Anfang nicht das heisst am Anfang kann er nur Sachen wie 3+6-8+5 (is auf dem quelltext den ich auf papier habe und später posten werde).
    und erst in der zweiten "Routine" ist das mit den Klammern möglich.
    Es wäre aber gut wenn dies schon bei der ersten Rechenoperation möglich wäre.
    Ich suche nach einem Weg, wo es eben egal ist was kommt.
    Vielleicht gibt es eine Formulierng bei scanf die dies zulassen würde.

    Ein anderes Bsp. mit selber Problematik wäre wenn Brüche bei der Eingabe so aussehen: a//b sollen.

    Bei / hat er Anweisungen zum dividieren.
    An die dritte Stelle könnte jetzt eine Zahl oder ein Zeichen kommen.

    Is nur ein Bsp.

    Ich mein unerwartete Eingaben müssen doch sehr oft vorkommen.



  • Hmmm, ist es möglich ne switch anweisung zu machen : so in der art

    switch (charvar)

    case '('

    Anweisung

    default

    und dann den Wert (falls möglich) in ne float variable "portieren"?

    Wie wandle ich eig den typ einer variable um und was passiert wenn man einen char wert in eine float variable einscant??

    Lg


Anmelden zum Antworten