Datei einlesen und Semantik überprüfen



  • Hi,
    Ich sitze hier gerade schon einige Zeit an dem Programm und als ich es gerad laufen lassen habe.. naja es passiert einfach nichts. Also es stürzt nicht ab, endet nicht und gibt nichts aus.
    Vielleicht könnt ihr mir ja weiter helfen:

    Das Programm soll aus einer Datei chars einlesen und überprüfen, ob die Semantik stimmt.
    Es dürfen die Variablen a,b,c vorkommen, es düfen Klammern gesetzt sein, + ist erlaubt und sin ist erlaubt.
    Falls da ein Fehler in der Datei ist (entweder ein falsches Zeichen oder eine unlogische Operation wie "+)" soll ein Fehler ausgegeben werden.

    Meine Idee ist die:
    Wenn a,b oder c eingelesen ist darf + oder ) folgen.
    Wenn sin eingelesen ist, darf ( folgen.
    etc. etc.

    Ein Switch führt je nach Zeichen eine Funktion aus. Eine While Schleife läuft so lange bis das Ende der Datei erreicht ist oder ein Fehler aufgetreten ist (dann wird das Zeichen zu einem '?').
    Danach wird überprüft ob das Ende der Datei erreicht ist, ob die Anzahl der offnen Klammern der der geschlossenen entspricht und ob das Zeichen kein Fragezeichen ist. (Es fehlen noch ein paar Kleinigkeiten, aber das ist egal).

    Hier der Code:

    #include <iostream>
    #include <fstream>
    using namespace std;
    
    int KlammerA=0;
    int KlammerB=0;
    
    char check_Var();
    char check_Sin();
    char check_oBracket();
    char check_cBracket();
    char check_Plus();
    
    char check_Var(ifstream &in)
    {
        char c;
        in >> c;
        if (c == '+')
        return '+';
        else if(c==')')
        return ')';
        return '?';
    
    };
    
    char check_Sin(ifstream &in)
    {
        char c;
        in >> c;
    
        if (c == 'i')
        {
            in >> c;
            if (c=='n')
            {
                in >> c;
                if(c=='(')
                   return '(';
            }
        }
        else
        return '?';
    
    };
    
    char check_oBracket(ifstream &in)
    {
        char c;
        in >> c;
        if(c == 'a' || c=='b' || c=='c')
        return 'a';
        else if (c=='s')
        {
            if (check_Sin(in)=='(')
            return '(';
        }
        else
        return '?';
    }
    
    char check_cBracket(ifstream &in)
    {
        char c;
        in >> c;
        if (c==')')
        return ')';
        else if (c=='+')
        return '+';
        else
        return false;
    }
    
    char check_Plus(ifstream &in)
    {
        char c;
        in >> c;
        if (c=='a' || c=='b' || c=='c')
            return 'a';
        else if(c=='(')
                return '(';
        else if (c=='s')
        {
            if(check_Sin(in)=='(')
            return '(';
        }
        else
        return '?';
    }
    
    int main()
    {
        ifstream in("text.txt");
        char c;
        in >> c;
    
      while ( 1 )
      {
       if (c=='?')
       break;
       if (in.eof())
       break;
    
        switch(c)
        {
            case('a') || ('b') || ('c') :
                c=check_Var(in);
                break;
    
            case ('s'):
                c=check_Sin(in);
                break;
    
            case ('('):
            {
                KlammerA++;
                c=check_oBracket(in);
            }
                break;
    
            case (')'):
            {
                c=check_cBracket(in);
                KlammerB++;
            }
                break;
    
            case ('+'):
                c=check_Plus(in);
                break;
    
            default: break;
        }
    
      };
    
    if (in.eof() && KlammerA==KlammerB &&c!='?')
        cout << "das Stimmt" <<endl;
    else
        cout << "error"<<endl;
    
    return 0;
    }
    

    Hoffe es geht halbwechs von der Verständlichkeit 🙂



  • Schau dir mal diesen Ausschnitt an:

    int main()
    {
      ifstream in("text.txt");
      char c;
      in >> c;
    
      while (true) {    
        if (c=='?' || in.eof())
          break;
        // ... viel Code, aber c bleibt konstant
      }
    }
    

    Falls du an einer C++-igeren Lösung als an deiner C-artigen interessiert bist, solche Dinge lassen sich über Boost.Spirit sehr leicht lösen.
    Hier im Forum gibts dazu sogar einen Artikel dazu: [url=http://magazin.c-plusplus.net/artikel/Boost%3A%3ASpirit%20-%20Eine%20Einf%FChrung]Boost::Spirit - Eine Einführung
    [/url]



  • das Problem ist, dass wir die Aufgabe nur mit dem lösen sollen, was wir bisher können. Also ein, zwei neue Befehle wären vielleich nicht schlimm, aber es geht... naja keine Ahnung worum es genau geht, aber nicht ums Ergebnis 😛

    Werds mir trotzdem später mal durchlesen.



  • Den letzten Rat kannst du ignorieren, aber dein c wird in der while-Schleife nicht neu ausgelesen, da liegt das Problem.



  • Hmm ich hab das jetzt nichts gefunden.. Was genau meinst Du?
    Meines erachtens ist es so:
    erster Char wird eingelesen und c zugewiesen.
    Es wird überprüft, was c ist und entsprechend wird etwas ausgeführt. Danach nimmt c einen neuen Wert an (in der Zwischenzeit ist das 'in' weiter nach vorne gerutscht). Dann beginnt die While Schleife von vorne und c wird wieder eingelesen...(?)



  • Schau dir noch mal genau den Hinweis von spiritualist an. Und ich würde für die Klammern nicht zwei Variablen nehmen, sondern nur eine. Die prüfst du dann zur Laufzeit, dass sie niemals kleiner 0 wird und am Ende 0 ist.

    Ah, ich sehe was du meinst. Das solltest du aber wirklich noch mal überdenken, ob man wirklich dort das Zeichen lesen sollte.



  • Was passiert, wenn das erste Zeichen, welches in c eingelesen wird, in keinen case-Zweig springt? ... dann hast du schonmal ne Endlosschleife und keine Ausgabe.



  • Hm ja stimmt. Habe also Default auf c='?' geändert. jetzt passts. Das Problem ist aber scheinbar, dass mein c kein Wert bekommt. Ich habe c vor der Schleife ausgegeben und es kommt nichts raus. Was ist an

    char c;
    ifstream in("text.txt");
    in >> c;
    cout << c;
    

    falsch?



  • Da kann vieles falsch sein:

    - ist deine text.txt befüllt?
    - ist das erste Zeichen auch wirklich kein Leerzeichen
    - Existiert die Datei im aktuellen Entwicklungsverzeichnis
    - Kann die Datei geöffnet werden. (siehe hierzu die Flags von ifstream good / fail / bad)
    - ist es wirklich schonwieder so spät? 😮



  • ja, sie ist befüllt mit a+b+c.
    das erste Zeichen ist kein Leerzeichen. Sie ist im demselben Verzeichnis wie die .cpp Datei. Und die Datei sollte eigentlich auch geöffnet werden können.
    Und: Ja, leider 😕


Anmelden zum Antworten