2017-07-24 1 views
0

Ich bin neu in der Sprache, also entschuldige mich, wenn ich einen dummen Fehler mache. Ich versuche, ein Mini-Spiel zu implementieren, wo Sie eine Geheimzahl durch den Computer in C. Hier erzeugte erraten ist der Code, den ich mit so weit habe kommen:Erraten Nummer Spiel in c lief in Schwierigkeiten

#include <stdlib.h> 
#include <stdio.h> 
#include <stdbool.h> 


int main(void) 
{ 
    int c=1; 
    bool running = 1; 
    int x = rand() % 20; 
    printf("The secret number is between 0 and 19, take a guess\n"); 
    int inp = getchar(); 
    while (running) { 
     if (inp==x) { 
      printf("Correct. Total number of guesses you spent was %i. Would you like to start a new game? Y/n", c); 
      bool running=0; 
     } 
     else if (inp>x) { 
      printf("guess smaller\n"); 
      scanf("%i", inp); 
     } 
     else if (inp<x) { 
      printf("guess larger\n"); 
      scanf("%i", inp); 
     } 
     c+=1; 
    } 
} 

Nach dem Kompilieren, das Spiel lief in Schwierigkeiten:

[email protected]:~/workspace$ ./guess 
The secret number is between 0 and 19, take a guess 
3 
guess smaller 
2 
Segmentation fault (core dumped) 

Was ist "Segmentierungsfehler"? Und wie kann ich das beheben?

+1

Ihr Einzug ist überall. Könnten Sie es bitte reparieren? –

+2

Nicht Ihre unmittelbare Sorge, aber 'bool running = 0;' wird * Shadow * die Variable in einem höheren Bereich definiert. – Bathsheba

+3

Wie würde 'int inp = getchar();' eine zweistellige Ganzzahl lesen ??? –

Antwort

3

Sie haben Segmentation fault (core dumped) Fehler aufgrund dieser Zeile:

scanf("%i", inp); 

Scanf Methode nimmt Zeiger als Argumente. Jetzt versucht das Programm einen neuen Wert in den Speicher zu schreiben, der nicht für unser Programm reserviert ist.

sollten Sie diese Zeile ersetzen durch:

scanf("%i", &inp); 
3

Eines der Probleme mit Ihrem Code ist, dass Sie falsch scanf verwenden. Der erste Parameter von scanf ist ein Format-String, und alle zusätzliche Parameter sollen ein Zeiger sein, so:

// Incorrect 
scanf("%i", inp); 

// Correct 
scanf("%i", &inp); 

Segmentation Fehler passieren, wenn Sie eine Speicheradresse zuzugreifen versuchen, die entweder ungültig oder Sie haben nicht die Zugriffsrechte. Angenommen, Sie führen Ihr Programm aus, und die erste Zahl, die Sie schreiben, ist 3, also inp = 3. Bis zu diesem Zeitpunkt läuft alles OK, da Sie die erste Nummer unter getchar lesen. Aber dann verwenden Sie scanf("%i", inp), so scanf wird die nächste Nummer unter der Adresse inp schreiben, d. H. Unter der Adresse 3, die eine Adresse ist, die Sie nicht schreiben können! Dadurch erhalten Sie einen Segmentierungsfehler.


Es gibt einen anderen Fehler in Ihrem Code, ein logischer Fehler jedoch. Sie lesen Ihre erste Nummer mit getchar: Was ist, wenn Sie eine Zahl größer als 9 eingeben möchten? Sie sollten auch scanf für den ersten Lesevorgang verwenden.

... 
printf("The secret number is between 0 and 19, take a guess\n"); 
int inp; 

// Not good 
inp = getchar(); 

// Good 
scanf("%i", &inp); 
... 

Auch Ihre while Schleife wird niemals enden, das heißt, wird Ihr Programm laufen für immer (wenn Sie es töten). immer dann, wenn in der Tat diese if Block ausgeführt:

if (inp == x) { 
    printf("Correct. Total number of guesses you spent was %i. Would you like to start a new game? Y/n", c); 
    bool running = 0; 
} 

Sie eine neue Variable bool running erklären, dass die zuvor erklärt running Variable überschreibt. Sie sollten ersetzen Sie es einfach mit:

if (inp == x) { 
    printf("Correct. Total number of guesses you spent was %i. Would you like to start a new game? Y/n", c); 
    running = 0; 
} 
+0

Ich versuchte getchar() und es schien gut zu funktionieren. Missinterpretiere ich etwas? – pxc3110

+0

Entschuldigung, mein Schlechter. Ich fand, dass wenn getchar() verwendet wird, es nicht gut für die größer als zwei Ziffern funktioniert, weil es "rate kleiner" und rate "größer" nacheinander, wenn Sie falsch raten, obwohl kein Problem für diejenigen mit einer einzigen Ziffer . Aber ich frage mich immer noch, warum es sich so verhält mit getchar(). – pxc3110

+0

@ pxc3110 die Probleme mit 'getchar' sind zwei: 1) Es liest nur das erste Zeichen der Zahl. Dies ist nur OK, wenn Sie Zahlen von 0 bis 9 lesen, aber in Ihrem Fall lesen Sie eine Zahl zwischen 0 und 20. 2) Es liest den ASCII-Tabellenwert des ersten Zeichens. Wenn Sie '1' schreiben, dann 'inp = 49' (werfen Sie einen Blick auf die ASCII-Tabelle für den Wert '1'). Also, wenn Sie 15 schreiben, dann wird 'getchar' nur' 1' und 'inp = 49' lesen, was nicht das ist, was Sie wollen. – ninjin

1

Zusätzlich zu den bisherigen Antworten, die korrekt den Grund für die Segmentierungsfehler weisen darauf hin, Sie viel mehr Probleme haben. Das folgende tut (ich denke), was Sie brauchen:

int main() 
{ 
    int c = 1; 
    bool running = 1; 
    srand(time(0)); 
    int x = rand() % 20; 
    printf("The secret number is between 0 and 19, take a guess\n"); 
    int inp; 
    scanf("%i", &inp); 
    while (running) { 
     if (inp == x) { 
      printf("Correct. Total number of guesses you spent was %i. Would you like to start a new game? Y/N", c); 
      char a; 
      scanf(" %c", &a); 
      if (a == 'N' || a == 'n') 
      { 
       running = 0; 
      } 
      else 
      { 
       c = 0; 
       srand(time(0)); 
       x = rand() % 20; 
       printf("The secret number is between 0 and 19, take a guess\n"); 
       scanf("%i", &inp); 
      } 
     } 
     else if (inp>x) { 
      printf("guess smaller\n"); 
      scanf("%i", &inp); 
     } 
     else if (inp<x) { 
      printf("guess larger\n"); 
      scanf("%i", &inp); 
     } 
     c += 1; 
    } 
} 

Dinge zu beachten. Sie müssen einen Startwert angeben, bevor Sie rand() aufrufen, andernfalls erhalten Sie eine Folge von Zahlen in der gleichen Reihenfolge. Normalerweise ist die aktuelle Zeit ein guter genug Samen.Zweitens müssen Sie die Antwort auf die Frage einlesen, ob der Benutzer fortfahren wollte oder nicht und entsprechend handeln. Hier dürfen Sie nicht running (mit bool) neu definieren, sonst erstellen Sie eine neue Variable, anstatt den Wert in der höheren Variablen zu ersetzen. Beachten Sie auch die Verwendung eines Leerzeichens, wenn Sie nach einem Zeichen fragen ("c%"). Dies ist notwendig, um zu vermeiden, dass das Programm die Eingabe zu überspringen scheint. Schließlich müssen Sie den Zähler zurücksetzen und x, wenn der Benutzer entscheidet, fortzufahren.

+0

Das sieht zu kompliziert aus. –

+0

@MichaelWalz Was ist der einfachere Weg? – pxc3110

+0

Beachten Sie, dass dieser Code nicht überprüft, dass 'scanf()' Erfolg, so ein Tippfehler wie ein Buchstabe anstelle einer Zahl wird es Probleme geben. –