Was ist mit Harald los?



  • Hi
    Warum wird bei folgendem Programm Haralds Name nicht abgefragt ???

    #include <iostream>
    #include <conio.h> // entfällt bei NICHT Dos Compilern
    
    using namespace std;
    
    int main()
    {
    
        cout <<"**********************************************\n"; 
        cout <<"*";
        cout <<" C++ Projekt von mir                         *\n";
        cout <<"*";
        cout <<" Frei von irgendwelchen Copyrightzeug        *\n";
        cout <<"**********************************************\n\n\n";
        cout <<"Uebung zu Strukturen\n";
    
        struct arbeiter
        {
               char name[30];
               int alter;
    
               };
    
        arbeiter heinz, harald;
    
        cout <<"Tragen Sie den ersten Arbeiter ein: \n";
        cin.getline(heinz.name, 30);
        cout <<"Sein Alter ??";
        cin >> heinz.alter;
    
        cout <<"Das gleiche Spiel nochmal: \n";
        cin.getline(harald.name, 30);
        cout <<"Sein Alter ??";
        cin  >>harald.alter;
        cout <<endl;
    
        cout <<"Name: "<<heinz.name <<endl;
        cout <<"Alter: "<<heinz.alter <<endl;
        cout <<"Name: " <<harald.name <<endl;
        cout <<"Alter: "<<harald.alter <<endl;
    
        getch(); // entfällt bei NICHT Dos Compilern 
        return 0;
    }
    

    Irgendwie seltsam... 😞



  • muss wohl irgendwas mit dem getline zu tun haben, denn ohne gehtz!



  • Morgen,

    das liegt daran, weil im Eingabepuffer noch das CR steht. Ein 'cin.get()' vor
    dem zweiten Einlesen schafft hier abhilfe.

    mfg
    v R



  • Soll ja um Strukturen gehen, dennoch sollte man das (imho) eher nicht so coden.

    Ausgabe bei der Ausfuehrung:
    **********************************************
    * C++ Projekt von mir *
    * Frei von irgendwelchen Copyrightzeug *
    **********************************************

    Uebung zu Strukturen
    Tragen Sie den ersten Arbeiter ein:
    asdfasdfasdfasdfasdfasdffffffffffffffffffffffffffffffffffffffffffff
    Sein Alter ??Das gleiche Spiel nochmal:
    Sein Alter ??
    Name: asdfasdfasdfasdfasdfasdffffff
    Alter: 2009303637
    Name:
    Alter: 2009145416

    OS: XP, Dev-C++ 4.9.9.2

    wobei meine einzige Eingabe bei Tragen Sie den ersten Arbeiter ein: aus asdfasdfasdfasdfasdfasdffffffffffffffffffffffffffffffffffffffffffff bestanden hat.
    Im In-Stream sind die Zeichen wohl generell noch drin.

    Wuerd sagen, das ist ein nettes Beispiel fuer einen Bufferoverflow, kann da aber auch falsch liegen. Vielleicht nimmt das mal wer auseinander, der es richtig kann?



  • hallo
    dieses beispiel hab ich schon in mehreren c++-buechern gesehen. es wurde aber
    meist nur ein arbeiter zu demo-zwecken herangezogen, sodass das 'getline' nicht
    auffiel.
    wenn der name laenger als 29 char ist, dann kann man den rest im alter
    decodieren.;)

    mfg f.-th.



  • sehe ich genauso wie virtuell Realisticer. ich versuch mal verständlich zu erklären, was er meint.

    bei cin.getline() liest alle zeichen bis einschließlich dem zeilenende-zeichen. cin<<heinz.alter liest aber nur ziffern ein. beim ersten zeichen, das keine ziffer ist bricht es ab. der rest der zeile, also auch das zeilenende-zeichen bleibt im puffer.

    wenn danach cin.getline() aufgerufen wird liest es die aus der letzten eingabe verbliebenen zeichen bis zum zeilenende ein! in der regel nur leerzeichen und line-feed. das sieht dann so aus, als würde getline() einfach übersprungen werden.

    gib mal bei der eingabe von cin<<heinz.alter nicht nur das alter sondern dahinter auch noch den namen harald ein:

    Tragen Sie den ersten Arbeiter ein: heinz
    Sein Alter ?? 34 harald
    Das gleiche Spiel nochmal: 
    Sein Alter ?? 22
    

    cin<<heinz.alter wird dann "34" einlesen und den rest " harald" im puffer stehen lassen. wenn dann getline() aufgerufen wird, liest es "harald" ein ohne daß du etwas eingegeben zu haben scheinst.



  • so funzts:

    #include <iostream> 
    #include <conio.h> // entfällt bei NICHT Dos Compilern 
    
    using namespace std; 
    
    void
    skip_line ()
    {
      char c;
    
      do cin.get(c); while(c!='\n');
    }
    
    int main() 
    { 
    
        cout <<"**********************************************\n"; 
        cout <<"*"; 
        cout <<" C++ Projekt von mir                         *\n"; 
        cout <<"*"; 
        cout <<" Frei von irgendwelchen Copyrightzeug        *\n"; 
        cout <<"**********************************************\n\n\n"; 
        cout <<"Uebung zu Strukturen\n"; 
    
        struct arbeiter 
        { 
               char name[30]; 
               int alter; 
    
               }; 
    
        arbeiter heinz, harald; 
    
        cout <<"Tragen Sie den ersten Arbeiter ein: "; 
        cin.getline(heinz.name, 30); 
        cout <<"Sein Alter ?? "; 
        cin >> heinz.alter; skip_line();
    
        cout <<"\nDas gleiche Spiel nochmal: "; 
        cin.getline(harald.name, 30); 
        cout <<"Sein Alter ?? "; 
        cin  >>harald.alter; skip_line();
        cout <<endl; 
    
        cout <<"Name: "<<heinz.name <<endl; 
        cout <<"Alter: "<<heinz.alter <<endl; 
        cout <<"Name: " <<harald.name <<endl; 
        cout <<"Alter: "<<harald.alter <<endl; 
    
        getch(); // entfällt bei NICHT Dos Compilern 
        return 0; 
    }
    


  • Ich hab da glaub noch was das abhilfe schafft.
    Du kannst nach jedem cin.getline() folgendes ein schieben;

    cin.clear() 
    cin.sync()
    

    cin.clear() löscht den Eingabepuffer und cin.sync() setzt alle Flags zurück die bei einem auftretenden Fehler (wie z.B. einem Overload) zurück.
    Danach sollte der Puffer wieder leer sein und du kannst ganz normal weitermachen.


Anmelden zum Antworten