2016-03-31 5 views
2

Frage 1-13 des Buches 'Die C-Programmiersprache' von K & R fordert den Leser auf, ein Programm zu erstellen, das ein Histogramm von Wörtern nach Länge erstellt. Die Wörter müssen vom Benutzer eingegeben werden.Besondere Ergebnisse. # 1-13 Das C-Programmiersprachenbuch

Ich habe versucht, ein Programm zu erstellen, das speichert, wie viele Wörter jeder Länge ihre dann den Int-Wert jedes Array-Blocks vor dem Umgang mit dem Histogramm ausdrucken. Egal wie sehr ich mit diesem Programm herumspiele, es wird mir immer eines von zwei Ergebnissen geben; entweder "1" oder was ich als eine Array-Adresse vermute? "6422476". Warum passiert dies?

#include <stdio.h> 
#define GREATEST 10 

int main(void){ 
    int c, word=0; 
    int word_count[GREATEST]; 

    /*set all values in word_count to 0*/ 
    for(int i=0; i<GREATEST; i++){ 
     word_count[i]=0; 
    } 

    while((c=getchar()) != EOF){ 
     if(c != ' '){ 
      ++word; 
     } else{ 
      word_count[word-1]=+1; 
      word=0; 
     } 
    } 

    for(int j=0; j<GREATEST; j++){ 
     printf("\n%d", word_count[j]); 
    } 
    return 0; 
} 
+2

1) Sie von der ersten Schleife bekommen können nur loswerden tun ' int word_count [GREATEST] = {0}; '2)' word_count [word-1] + = 1; 'verursacht Probleme, wenn' word' gleich '0' ist, sagen wir, wenn die erste Zeicheneingabe ein Leerzeichen ist; 3) Sie zählen nie das letzte Wort; 4) Sie werden Zeilenumbrüche, Punkte und andere Nicht-Buchstaben-Zeichen in Ihre Wortanzahl einschließen. –

+0

@Paul Griffiths Meine einzige Frage ist zu Ihrem dritten Punkt, würde nicht für (int j = 0; j Dynathus

+0

Diese Schleife druckt das Histogramm, es hat nichts damit zu tun, Wörter zu zählen. Sie zählen nur ein Wort, wenn Sie auf ein Leerzeichen stoßen. Wenn das letzte Zeichen, das Sie gelesen haben, ein Leerzeichen ist, wird 'word_count [word-1] + = 1;' 'nicht für das letzte Wort ausgeführt, so dass es nicht gezählt wird. –

Antwort

2

Es gibt einen guten Grund, warum Sie immer 1. Beachten Sie bekommen würde, dass

word_count[word-1]=+1; // This assigns to the value "+1"!` 

sollte

word_count[word-1]+=1; // This increments your array item` 

Es ist ein Scheiß, was in C kompiliert :).

+0

'= +' war ein Operator in alten C! Auch könnten diese Operatoren einmal mit Leerzeichen in ihnen geschrieben werden wie in '+ ='. – Kaz

+2

Siehe hier: https://www.bell-labs.com/usr/dmr/www/chist.html Quote: * "In B und frühen C, der Operator wurde geschrieben = + anstelle von + =; dieser Fehler, repariert im Jahr 1976, wurde durch eine verführerisch einfache Art der Handhabung der ersten Form in B lexikalischen Analysator induziert. "* Gerade von Dennis Ritchie. – Kaz

+0

das macht Sinn, aber warum dann würde es .... Sie erhalten das Bild sein – Dynathus

0

lief ich Ihren Code entweder mit der richtigen += oder ‚nicht korrekt‘ =+ und beide gaben die gleiche Leistung:

a bb bb ccc ccc ccc dddd dddd dddd dddd qwertyuiop eeeee 

1 2 3 4 0 0 0 0 0 1 

a bb bb ccc ccc ccc dddd dddd dddd dddd qwertyuiop eeeee 

1 2 3 4 0 0 0 0 0 1 

jedoch sowohl das letzte Wort eingegeben fallen gelassen - Null für eine 5 Zeichenlänge Wort. Ich denke, das ist, weil Sie die While-Schleife auf EOF wie ctrl + D und was auch immer seit dem letzten Leerzeichen ' ' nicht verarbeitet wurde beendet wurde.

Auch wenn der Benutzer "Wörter" oder Gruppen von "Wörtern" eingibt, die durch Leerzeichen in mehr als einer Zeile getrennt sind, sind die Ergebnisse nicht korrekt. Diese "Optionen" für die Eingabe von Wörtern erschweren die konsistente Verarbeitung von Eingaben.

Sie können den Benutzer möglicherweise anweisen, jeweils ein Wort einzugeben und Eingaben zu verwerfen, die ein Leerzeichen enthalten. Dies erleichtert die Steuerung der Eingabe und die Verarbeitung aller eingegebenen Wörter.

Hier ist ein Code-Schnipsel für die Eingabe mit einem Puffer, um die Eingabe zu halten. Die Puffergröße, das Histogramm-Array und die maximal zulässige Wortlänge werden mit einer statischen Variablen maxlen festgelegt.

/* tell user what to enter */ 
printf("Type one word at a time (hit enter after each word)\nType 99 to finish\n"); 

/* get lines of input */ 
while ((fgets(buff, maxlen ,stdin)) != NULL) { 
    /* test for '99' end code */ 
    if(strncmp(buff, "99", 2) == 0) break; 
    /* test for any spaces in input -if so ignore input & print message */ 
    if(strstr(buff, " ") != NULL) { 
     printf("Enter one word at a time - then hit enter\n"); 
     } else { 
     /* else get size of word (-1 for newline) & increment appropriate counter */ 
     length = strlen(buff) - 1; 
     hist[length]++; 
    } 
} 

Der Puffer war Setup wie diese

char *buff = malloc(maxlen + 1); 

und muss free'd werden, sobald die Eingabe abgeschlossen ist

free(buff); 
Verwandte Themen