simple Frage zu gets(*char)



  • Hi! Ich habe gerade angefangen mit C++ zu Experimentieren.
    Ich benutze DEV C++ IDE

    Dieser code soll den Benutzer nach 'y' oder 'n' abfragen und eventuell das Programm beenden.

    Hier sind 2 Beispiele die beide vom Compiler akzeptiert worden sind aber beim ersten Beispiel strutzt das Programm ab.

    first attempt:

    ...
      char* choice;
      gets(choice);
      if (*choice != 'y') {
        printf("Program terminated by user\n\n");
        system("PAUSE");
        exit(1);
      }  
      ...
    

    Die erste probe wurde ohne Fehler compiliert aber das Programm sturtzte ab. Die Helpfile besagt dass gets() einen Zeiger als Argument braucht, also deklarierte ich:

    char* choice;
    

    was sich jedoch als falsch erwies (warum?)

    Nach folgenden Veranderungen funktionierte das Programm wider:

    second attempt:

    ...
      char choice;
      gets(&choice);
      if (choice != 'y') {
        printf("Program terminated by user\n\n");
        system("PAUSE");
        exit(1);
      }  
     ...
    

    Der zweite Code funktioniert einwandfrei.

    Was ist falsch im ersten Beispiel das das System absturzen lasst? (Win XP)

    Vielen danke fur die Hilfe. (Bitte enschuldigt Sprachfehler)



  • char* choice;
    

    das ist nur ein zeiger... der zeigt irgendwo hin ins nirvana und wenn du dahin zeichen einliest ist es dum zufall überlassen ob das programm abschmiert oder was auch immer macht...

    nimm ein char-array... also z.b.

    char choice[1024];
    

    wenn du nur ein zeichen einlesen willst tuts auch

    char choice;
    

    allerdings kannst du dann kein gets verwenden weil ein string immer 0-terminiert ist... hierfür dann getchar oder sowas verwenden... ach so nochwas gets ist ein wenig riskant da du leicht nen bufferoverflow bekommen kannst wenn der user mehr zeichen einliest als der buffer gross ist, ggf lieber fgets verwenden...

    da du allerdings ins c++-forum postet kannst du dich dieses problems auch leichter entledigen indem du einfach std::string verwendest...

    std::string choice;
    std::cin>>choice;
     if (*choice != "y") {
        std::cout<< "Program terminated by user\n\n";
        exit(1);
      }
    


  • Vielen dank fur deine Antwort! Jetzt ist mir alles verstandlich.



  • Das ist nicht ganz korrekt, gets liest eine Zeile input ein. gets ist allerdings gefährlich, weil es u.U. über die Länge des Buffers in Speicher hineinschreiben kann, der dir nicht gehört. In C ist es deshalb idR sinnvoller, fgets zu benutzen, also:

    char choice[1024];
    fgets(choice, 1024, stdin); /* Eine Zeile, aber höchstens 1024 Zeichen aus stdin lesen und nach choice schreiben */
    if(choice[0] == 'y') {
      /* ... */
    }
    

    Damit ist zwar die maximale Länge der Eingabe auf die Länge des Buffers beschränkt, aber das ist immer noch besser als ein Segfault, oder dass er dir in irgendwelche anderen Bereiche auf dem Stack schreibt.

    In C++ dagegen sähe das so aus:

    std::string choice;
    std::getline(std::cin, choice); // Eine Zeile in choice lesen
    
    if(choice[0] == 'y') {
      // ...
    }
    

    Da übernimmt std::string das Speichermanagement für dich, von daher wird das idR die sinnvollere Alternative sein.


Anmelden zum Antworten