Unerwünschte Symbole - Mein erstes C-Programm



  • Zeile 46: Kannste ersetzen durch zuratendeswort[strlen(zuratendeswort) - 1] = '\0';

    Zeile 49: Es ist in C üblicher, Variablen am Anfang des Scopes zu deklarieren, da nicht alle Compiler das Schlucken.
    Zeile 50: Das ist in C(89) nicht üblich, Arraygrößen müssen konstant sein. (Zur Compilezeit feststehen). Zudem brauchst du strlen() + 1 Platz, und die Variable "wortlaenge" ist sinnlos.

    Zeile 55: Die Schleife kopiert das '\0' am Ende nicht mit, (was im übrigen auch ein Fehler wäre, da "daswort" zu klein ist). Wie auch immer, du müsstest es mit kopieren um einen gültigen String zu erhalten.

    Weiter habe ich erstmal nicht gelesen.

    Edit:
    Zeile 88: fflush(stdin) ist böse.



  • Danke für deine Hinweise.
    Ich werde das Programm jetzt erstmal überarbeiten, und mit feste Arraygrößen arbeiten.



  • Den Zeilenumbruch und die Grossschreibung ein wenig anders zusammen gesetzt.
    Zeile 40 bis 65:

    int i;
    
        printf("Satz oder Wort eingeben : ");
        fgets(zuratendeswort, MAX, stdin);            // wort eingeben und zeilenumbruch (\n) durch stringende (\0) ersetzen
    
        int wortlaenge = strlen(zuratendeswort);
        char daswort[wortlaenge];
        printf("\n%s\n\n", zuratendeswort);
    
        // wort in großbuchstaben umwandel und in ein neuen char kopieren
    
        for(i=0; i < wortlaenge-1; i++){	// nur bis \n lesen
            if(isalpha(zuratendeswort[i])){
                daswort[i] = toupper(zuratendeswort[i]);
              }
            else{
                daswort[i] = zuratendeswort[i];
            }
        }
        daswort[i] = '\0';		// ihr wisst schon
    
        printf("%s\n\n", daswort);        // zeigt hinter dem wort irgendwelche zeichen an    !!!!
    


  • Danke dafür...
    Das hat mir sehr geholfen. Ich hatte da eine kleinen Gedankenfehler.
    Ein Array fängt ja immer bei Null an zu zählen, dass hatte ich in dem Moment nicht berücksichtigt.

    Mir ist auf gefallen, bei einem kleinen Test, dass auch ohne

    daswort[i] = '\0';
    

    das '\n' scheinbar verschwunden ist. Wie kommt das? Und, wurde der String dann trotzdem mit '\0' beendet?

    Ich hatte das mit diesem kurzem Programm probiert.

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    #define MAX	51
    
    int main(void){
    
    	char zew[MAX] = {0};	
    	char dmy[MAX] = {0};	
    
    	int i;
    
    	printf("Wort oder Satz eingeben: ");
    	fgets(zew, MAX, stdin);
    
    	for(i = 0; i < strlen(zew)-1; i++){
    		dmy[i] = zew[i];
    	}
    	//dmy[i] = '\0';
    
    	printf("%s hat %d zeichen\n", dmy, strlen(dmy));
    
    	return EXIT_SUCCESS;
    }
    


  • egens schrieb:

    Danke dafür...
    Das hat mir sehr geholfen. Ich hatte da eine kleinen Gedankenfehler.
    Ein Array fängt ja immer bei Null an zu zählen, dass hatte ich in dem Moment nicht berücksichtigt.

    Mir ist auf gefallen, bei einem kleinen Test, dass auch ohne

    daswort[i] = '\0';
    

    das '\n' scheinbar verschwunden ist. Wie kommt das? Und, wurde der String dann trotzdem mit '\0' beendet?

    Ich hatte das mit diesem kurzem Programm probiert.

    Die Null-Terminierung hast du bei deinem Testprogramm schon gegeben, weil die Arrays sauber initialisiert sind. Und das Newline hast du bei deiner for()-Schleife nicht mitkopiert (wozu soll die überhaupt gut sein?).



  • Darum geht es ja.
    Newline sollte nicht mitkopiert werden.

    Jetzt ist der Groschen gefallen, just in dem Moment wo ich schreiben wollte, dass ich nicht verstehe warum das newlin nicht mitkopiert wurde...

    Bei dem String "TEST\n" befindet sich newline im Array an vierter Stelle.
    diese for-Schleife ...

    for(i=0; i < strlen("TEST\n")-1; i++);
    

    ... würde aber in diesem Fall nur so lange durchlaufen wie i kleiner ist als 4 und nicht bis 4, wo sich newline befindet. Somit wird es nicht mehr mitkopiert.

    Manchmal sieht man den Wald vor lauter Bäumen nicht mehr. 🙂



  • egens schrieb:

    Darum geht es ja.
    Newline sollte nicht mitkopiert werden.

    Gegenfrage: Warum mußt du die Eingabe überhaupt kopieren - es geht doch wesentlich schneller, im Original-Array das Newline mit '\0' zu überschreiben als alle anderen Zeichen in ein zweites Array zu kopieren.



  • Das ist eigentlich nicht mehr wichtig. Ich habe das Programm schon dahingehend geändert, und der Text wird nicht mehr kopiert. Ich wollte nur wissen, warum ich vorher an dieser Stelle Probleme hatte. Wo mein Fehler war.
    Damit ich ihn später nicht wiederhole.



  • So, um zu einem Abschluss zu kommen, hier der Code der ohne Probleme funktioniert.
    Danke für eure Hilfe.

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <ctype.h>
    
    #define MAX	51
    #define VSH 7
    
    int main(void){
    
    	char zew[MAX] = {0};	// Zu eratenes Wort
    	char dmy[MAX] = {0};	// Dummy
    
    	char bsn[30]  = {0};	// Buchstaben
    
    	char buf[3]	  = {0};
    	char ege;				// Eingabe
    
    	int wl  = 0;			// Wortlänge
    
    	int zlr = 0;			// zähler für Buchstaben
    	int gdn = 0;			// gefunden
    	int flr = 0;			// fehler
    
    	int i;
    
    	printf("Wort oder Satz eingeben: ");
    	fgets(zew, MAX, stdin);
    	wl = strlen(zew);
    	for(i = 0; i < wl-1; i++){                // Dummy erstellen und Wort in Großbuchstaben umwandeln
    		if(isalpha(zew[i])){
    			dmy[i] = '-';
    			zew[i] = toupper(zew[i]);
    		}
    		else{
    			dmy[i] = zew[i];
    		}
    	}
    	zew[i] = '\0';
    
    	while(strcmp(zew, dmy) != 0 && flr < VSH){
    
    		printf("===============================================================================\n\n");
    
    		printf("Bereits verwendete Buchstaben: ");
    		for(i = 0; i < (int)strlen(bsn); i++){
    			printf("%c ", bsn[i]);
    		}
    		printf("\n\n");
    
    		printf("     Gesuchtes Wort bze. Satz: %s\n\n", dmy);
    
    		printf("           Buchstabe eingeben: ");
    
    		scanf("%c", &ege);
    		fflush(stdin);
    
    		printf("\n\n===============================================================================\n\n");
    
    		if(isalpha(ege)){
    			ege = toupper(ege);
    		}
    
    		if(!strchr(bsn, ege)){
    			bsn[zlr] = ege;
    			zlr++;
    
    			for(i = 0; i < wl-1; i++){
    				if(zew[i] == ege){
    					dmy[i] = ege;
    					gdn = 1;
    				}
    			}
    		}
    		else{
    			printf("!!! Den Buchstaben hattest du schon.\t>> %c\n\n", ege);
    		}
    
    		if(gdn == 0){
    			flr++;
    			printf("!!! Das war falsch.\t\t\t>> Noch %d Versuche.\n\n", VSH-flr);
    		}
    		else{
    			printf("!!! Das war richtig.\n\n");
    			gdn = 0;
    		}
    
    	}
    	printf("===============================================================================\n\n");
    	if(flr < VSH){
    		printf("!!! Glueckwunsch, Du hast das gesuchte Wort erraten. >> %s\n\n\n", zew);
    	}
    	else{
    		printf("!!! Du hast leider Verloren. Mehr Glueck beim naechsten Mal.\n\n\n");
    	}
    
    	return EXIT_SUCCESS;
    }
    

    ps.: ja ih weiß fflush(stdin) ist böse 😉



  • Hier noch mal eine Version von mir, vielleicht mal ganz nett für dich zu sehen, wie man das noch hätte machen können. (Jetzt kommt bestimmt gleich wieder einer der eine Verbesserung vorschlägt :D)

    int compare(const char *base_str, char *dest_str, char c)
    {
      int rval = 0;
      while (*base_str)
      {
        if (*base_str == c)
        {
          *dest_str = c;
          ++rval;
        }
        ++base_str;
        ++dest_str;
      }
      return rval;
    }
    
    int main(int argc, char *argv[])
    {
      char secret[0x100];
      char word[0x100];
      int i, counter = 0, c;
    
      printf("Enter secret word: ");
      fgets(secret, sizeof(secret), stdin);
      secret[strlen(secret) - 1] = '\0';
      for (i = 0; i < strlen(secret); ++i) // geht schöner mit Pointern ;)
      {
        secret[i] = toupper(secret[i]);
        word[i] = '_';
      }
      word[i] = '\0';
    
      while (counter < 10)
      {
        printf("Enter char: ");
        while ((c = getchar()) == '\n')
          ;
        if (!compare(secret, word, toupper(c)))
          ++counter;
        printf("Actual word: %s\n", word);
        if (!strcmp(secret, word))
          break;
      }
      if (counter >= 10)
        puts("Game over :(");
      if (counter < 10)
        puts("You win!");
    
      return 0;
    }
    

Anmelden zum Antworten