Palindrom: Problem beim entfernen von Sonderzeichen



  • Hallo, da ich neu bin stell ich mich erst Mal kurz vor. Meine Name ist Stefan und bin Informtaikstudent im 1.Semester und habe folgende Aufgabenstellung bekommen:

    Schreiben Sie ein Programm, welches
    a) einen Text ohne Leer- und Satzzeichen einliest,
    b) alle Zeichen außer Buchstaben aus dem Text entfernt,
    c) den veräanderten Text wieder ausgibt,
    d) die Länge des Textes ermittelt,
    e) den Text in umgekehrter Reihenfolge ausgibt,
    f) und entscheidet, ob dieser Text ein Palindrom ist oder nicht.

    #include<stdio.h>
    #include<string.h>
    #include<ctype.h>
    
    int main(void){
    
        int inputLenght = 0, counter = 0;
    	char input[255],  workingCopy[255], output[255], test[255];
    	printf("Palindrom\n");
    	printf("Geben Sie einen Text ein: ");
    	fgets(input, sizeof(input) , stdin);
            inputLenght = strlen(input);
    
    	for(counter=0;counter<inputLenght;counter++)
            {
              if (isalpha (input[counter]))
              {
    	      workingCopy[counter]=input[counter];
              }
              test[counter] = workingCopy[counter]; 
            }
    
    	inputLenght = strlen(workingCopy);
    
    	for(counter = 0; counter<inputLenght; counter++){
    
    		if (workingCopy[inputLenght-1-counter] != 0) {
    			output[counter] = workingCopy[inputLenght-1-counter];
    		}
    
            }
    
    	if (output == workingCopy) {
    	printf("Es handelt sich um ein Palindrom!\n");
        } else {
    
    	printf("Es handelt sich um kein Palindrom!\n");
        }
    
    	printf("%s\n", output);
    	printf("%s\n", test );
    
      	return 0;
    
    }
    

    Mein Problem was ich habe und nicht verstehe ist folgendes: bei der Eingabe von "hallo1234----" gibt er mir nach dem Entfernen von sonderzeichen dies bei "test" aus:
    "hallo(und dann 4 Kryptischezeichen)"
    und bei "output":
    "(6Kryptischezeichen)ollah"!
    Lass ich die beide "-1" bei der zweiten for-schleife weg bekomme ich nur eine Ausgabe bei "test": "hallo{".

    so langer Text kurze Frage: Warum diese seltsamen Ausgaben.



  • Ein String muss mit einer 0 als Terminierungszeichen beendet werden. Tut man das nicht, gibts Datenmüll. Und bei deiner workingCopy gibt es, so weit ich das sehe, kein Terminierungszeichen.

    Du kriegst übrigens auch Blödsinn, wenn du etwas wie "abc123cd" einliest, da dann statt "123" nichts reingeschrieben wird, du also irgendwelche Daten ausliest, aber nichts sinnvolles.

    if (output == workingCopy)
    

    So ein Vergleich funzt auch nicht, da nicht der Inhalt verglichen wird. Schau dir die strcmp Funktion an.



  • ok danke erstmal hab jetzt ein bisschen rumprobiert aber bekomm keine wünschenswerte Ergebnisse.
    also meine frage jetzt:
    wie bekomm ich das jetzt hin das wenn man etwas beliebiges eingibt kein Datenmüll für zahlen oder ähnliches einließt, sondern alles einließt und dann nur die Buchstaben zurückgibt.
    Ich dachte nämlich, dass er in dem Array jetzt alle Zeichen einließt ohne datenmüll und das die Funktion "isalpha" dann nur die Buchstaben zurückgibt.
    Wäre schön wenn ihr mir da hinweise geben könnt.



  • Benutz zwei Zähler. Einmal deinen counter, der jedesmal hochgezählt wird wenn du ein Zeichen aus dem input[] liest. Und dann noch einen, der nur hochzählt, wenn du was in workingCopy schreibst. Damit kannst du dann lückenlos nach workingCopy schreiben. Am Ende wenn du mit dem schreiben fertig bist, packst du nach dem letzten Buchstaben noch eine 0 in workingCopy.



  • vielen dank für die schnelle Antwort, werde ich mich dann mal ans "basteln" machen und hoffen das es klappt^^

    mfg

    kannst du mir noch erklären warum ich zwei zähler brauche weil eigentlich haben die beide dann doch immer den gleichen Wert oder haben ich deine Idee nicht richtig verstanden. 😕

    und sorry bin noch ein noob in ANSI C 😉



  • loonie schrieb:

    b) alle Zeichen außer Buchstaben aus dem Text entfernt,

    dafür gibts: http://www.cplusplus.com/reference/clibrary/cctype/isalpha/
    🙂



  • Das benutzt er doch sogar schon 😉



  • Genmutant schrieb:

    Das benutzt er doch sogar schon

    ok, ich war wieder zu schnell, hab den code nicht beachtet.
    🙂



  • loonie schrieb:

    kannst du mir noch erklären warum ich zwei zähler brauche weil eigentlich haben die beide dann doch immer den gleichen Wert

    Also guck, wir nehmen mal als Beispiel des input "ab12cd".
    Am Anfang sind die beiden Zähler, counter und counter_buchstaben nennen wir sie mal, beide gleich groß, weil du ja beide hochzählst, wenn du schreibst.
    dann schauen deine beiden arrays so aus bis zu dem Wert vom counter:
    input: ab
    workingCopy: ab
    so, jetzt kommen deine Zahlen. Da zählt der normale counter hoch. Wenn du da jetzt einfach nur nicht schreiben würdest, hättest du sowas:
    input: ab12
    workingCopy: ab[müll][müll]
    Das würde dazu führen dass du am Ende, wenn du das auf die gleiche Stelle kopierst, sowas hast:
    workingCopy: ab[müll][müll]cd

    Jetzt machst du das aber mit 2 Zählern. Der counter_buchstaben wird nur hochgezählt, wenn du auch wirklich was nach workingCopy schreibst.
    D.h. die Zuordnung wird: workingCopy[counter_buchstaben]=input[counter];

    Drum hast du dann am Ende:
    input(bis counter): ab12cd
    workingCopy(bis counter_buchstaben): abcd

    Verstanden? 🙂



  • oder mach dir doch 'ne funktion zum rausfiltern von nicht-buchstaben. beispiel:

    void letters_only (char *str)
    {
        char *p = str;
        while (*str)    // string abklappern bis ende
        {
            if (isalpha(*str)) // buchstabe?
            {
                *p++ = *str;  // ja, dann übernehmen  
            }
            str++;            // naechstes zeichen
        }
        *p = 0;               // mit 0 abschliessen
    }
    
    void main()
    {
        char test[] = "1234ha77.llo88 du da){";
        letters_only (test);
        puts (test);
    }
    


  • Schöne Sache, sogar ohne zusätzliches Array 👍



  • Genmutant schrieb:

    Schöne Sache, sogar ohne zusätzliches Array

    danke, bin nun mal ein grosser freund von sparmassnahmen. naja, aber sollte ein zweites array nötig sein, lässt sich die funktion auch ganz leicht umbauen.
    🙂



  • ;fricky schrieb:

    char *p = str;
        while (*str)    // string abklappern bis ende
        {
            if (isalpha(*str)) // buchstabe?
            {
                *p++ = *str;  // ja, dann übernehmen  
            }
            str++;            // naechstes zeichen
        }
        *p = 0;               // mit 0 abschliessen
    


  • jetzt hab ich kapiert warum zwei zaehler, besten dank dür die Erklärung Genmutant!
    hatte jetzt noch keine Zeit es umzuschreiben.

    und danke für die "Teilmusterlösung" aber werde mein Programm umschreiben... da steckt dann doch der ergeiz hinter, es zum lauifen zum bringen.

    mfg



  • so hab das Programm jetzt fertig:

    #include<stdio.h>
    
    #include<string.h>
    
    #include<ctype.h>
    
    int main(void){
    
            int inputLenght = 0, counter = 0, counterWrite = 0 ;
    
    	char input[255],  workingCopy[255], outputPalindrom[255], output[255];
    
    	printf("Palindrom\n");
    
    	printf("Geben Sie einen Text ein: ");
    
    	fgets(input, sizeof(input) , stdin);
    
            inputLenght = strlen(input);
    
    	for(counter=0;counter<inputLenght;counter++)
    
            {
    
              if (isalpha (input[counter]))
    
              {
    	      	workingCopy[counterWrite]=input[counter];
    
    		counterWrite++;
    
              }
    
            }
    
    	workingCopy[counterWrite] = '\0';
    
    	inputLenght = strlen(workingCopy);
    
            for(counter = 0; counter<inputLenght; counter++){
              if(islower(workingCopy[counter])){
    
                workingCopy[counter] = toupper(workingCopy[counter]);
    
              }
    	  output[counter] = workingCopy[counter];
            }
    
    	output[counterWrite] = '\0';
    
    	workingCopy[counterWrite] = '\0';
    
    	for(counter = 0; counter<inputLenght; counter++){
    
    	  outputPalindrom[counter] = workingCopy[inputLenght-counter-1];
    
            }
            outputPalindrom[counter] = '\0';
    
            printf("\n");
            printf("Ihre Eingabe nachdem entfernen aller Zeichen ausser Buchstaben ist:\n");
            printf("%s\n", output);
            printf("\n");
            printf("Die neue laenge Ihrer Eingabe ist:\n");
            printf("%d\n", inputLenght);
            printf("\n");
            printf("Die Ausgabe in umgedrehter Reinfolge ist:\n");
            printf("%s\n", outputPalindrom);
            printf("\n");
    
    	if(strncmp(output, outputPalindrom, inputLenght)==0)
            {
              printf("Bei der Eingabe handelt es sich um ein Palindrom!\n"); 
            }
            else
            {
              printf("Bei der Eingabe handelt es sich um kein Palindrom!\n");
            }
    
    	printf("\n");
    
      	return 0;
    
    }
    

    und ein Dankeschön für die Hilfe

    hab doch noch eine Frage und zwar bekomme ich wenn ich mit der Option -O2 (gcc -O2 Palindrom.c) compiliere bekomme ich diesen Fehler:
    "Palindrom.c:25: warning: ignoring return value of ‘fgets’, declared with attribute warn_unused_result"


Anmelden zum Antworten