Palindrom in C erkennen



  • ok das wars, nun geht es... das 1. ist mir klar. i war um 1 zu hoch.
    kannst du das 2. nochmal genau erkläre, was macht genau das =0?

    rkhb schrieb:

    vfbf4n1893 schrieb:

    ach ok, hab das geändert in %s und das & weggemacht. leider sagt er immer noch jedes mal das es kein palindrom ist, egal was ich eingebe.

    Noch zwei Fehler:

    1. Die Anzahl der Zeichen in string ist nicht der letzte Index in der Zeichenkette string. Füg mal hinter die While-Schleife noch ein
    i--;
    

    ein.

    1. string2 hat noch keine Abschlussnull. Füg mal hinter die For-Schleife noch ein
    string2[j]=0;
    

    ein.

    viele grüße
    ralph



  • Weißt du wofür die '\0' (oder 0) in einem String da ist?



  • das ist immer das letzte zeichen im string, das weiß ich. jedoch weiß ich nicht, was der befehl soll string2[j]=0;



  • vfbf4n1893 schrieb:

    das ist immer das letzte zeichen im string, das weiß ich. jedoch weiß ich nicht, was der befehl soll string2[j]=0;

    Welchen Wert hat denn j am Ende der for-Schleife?



  • vfbf4n1893 schrieb:

    kannst du das 2. nochmal genau erkläre, was macht genau das =0?

    rkhb schrieb:

    ...
    2) string2 hat noch keine Abschlussnull. Füg mal hinter die For-Schleife noch ein

    string2[j]=0;
    

    ein.

    Ein C-String besteht nicht nur aus den Buchstaben, sondern zusätzlich noch aus einer Null hintendran. Damit weiß man, wo der String zu Ende ist. Ein Wort aus 5 Buchstaben benötigt also ein Zeichenkettenarray mit (mindestens) 6 chars. Bei Deinem Programm zeigt j nach Beendigung der For-Schleife auf das Byte hinter den Buchstaben. Genau dort gehört eine Null hin und genau dorthin wird eine Null gespeichert.

    viele grüße
    ralph



  • 4?, ach da sagst du dem string, dass er hier fertig ist. ansonsten kommen irgendwelche werte da hin?



  • Genau.

    Die Erklärung hat schon rkhb geschrieben.



  • und wenn ich den scanf befehl ausführe wird beim 1. string die 0 automatisch drangehängt?



  • Swordfish schrieb:

    #include <ctype.h>
    #include <string.h>
    #include <stdio.h>
     
    int is_palindrome( char const *beg, char const *end )
    {
        if( !( beg && end ) )
            return 0;
     
        --end;
     
        if( !*end || !isprint( *end ) )
            --end;
     
        while( beg < end )
            if( *beg++ != *end-- )
                return 0;
     
        return 1;
    }
     
    int main()
    {
        char const *text = "abcba";
        printf( "\"%s\" %s a palindrome.", text,
            is_palindrome( text, text + strlen( text ) + 1 ) ? "is" : "isn't" );
    }
    

    Ähm, isprint in einem Wort? 🤡

    int is_palindrome ( const char* s )
    {
    	char* a = s, *b = a + strlen( s ) - 1;
    	while ( *a == *b && a < b )
    		a++, b--;
    	return *a == *b;
    }
    
    int main ( void )
    {
    	printf ("%d\n", is_palindrome ( "ABBA" ));
    	printf ("%d\n", is_palindrome ( "ABxBA" ));
    	printf ("%d\n", is_palindrome ( "A" ));
    	printf ("%d\n", is_palindrome ( "AA" ));
    	printf ("%d\n", is_palindrome ( "!AaaahhhaaaA!" ));
    	printf ("%d\n", is_palindrome ( "blubb" ));
    	return 0;
    }
    

    vfbf4n1893 schrieb:

    das ist immer das letzte zeichen im string, das weiß ich. jedoch weiß ich nicht, was der befehl soll string2[j]=0;

    Angenommen der string ist char string2[] = "Ottos Motto"; int j = 4;
    Dann verkürzt die Zuweisung string2[j] = 0; den String denn ein strlen(string2) liefert nun einen anderen Wert als vor der Zuweisung und ein puts(string2); zeigt Otto an. Alle Buchstaben bis auf das s, das durch die 0 ersetzt wurde, sind aber immer noch im char Array enthalten.



  • vfbf4n1893 schrieb:

    und wenn ich den scanf befehl ausführe wird beim 1. string die 0 automatisch drangehängt?

    Ja.
    Alle Stringfunktionen tun dies und verlassen sich auch darauf, das eine 0 am Ende ist.

    Alle? Nein! strncpy macht das nicht immer.



  • CJosef schrieb:

    Ähm, isprint in einem Wort? 🤡

    Denkfehler bei der Umsetzung oben, aber:

    #include <ctype.h>
    #include <string.h>
    #include <stdio.h>
    
    int my_is_palindrome( char const *beg, char const *end )
    {
    	if( !( beg && end ) )
    		return 0;
    
    	--end;
    
    	if( !*end )
    		--end;
    
    	while( !isprint( *end ) )
    		--end;
    
    	while( beg < end )
    		if( *beg++ != *end-- )
    			return 0;
    
    	return 1;
    }
    
    int your_is_palindrome( const char* s )
    {
        char const * a = s, *b = a + strlen( s ) - 1;
        while ( *a == *b && a < b )
            a++, b--;
        return *a == *b;
    }
    
    int main()
    {
    	char buffer[ 80 ];
    
    	fgets( buffer, sizeof( buffer ), stdin ); // <- ABBA
    
    	printf( "%s", buffer );
    
    	printf( "my_is_palindrome():   %d\n",   my_is_palindrome( buffer, buffer + strlen( buffer ) + 1 ) );
    	printf( "your_is_palindrome(): %d\n", your_is_palindrome( (char const*) buffer ) );
    }
    


  • Swordfish schrieb:

    CJosef schrieb:

    Ähm, isprint in einem Wort? 🤡

    printf( "my_is_palindrome():   %d\n",   my_is_palindrome( buffer, buffer + strlen( buffer ) + 1 ) );
    	printf( "your_is_palindrome(): %d\n", your_is_palindrome( (char const*) buffer ) );
    }
    

    🤡

    Das \n pult man vor der Benutzung des Puffers während der Eingabe in einer schnuckelig ausgelagerten Eingabefunktion raus.
    💡 Dann brauchen sich die zig Millionen Funktionen in deinem Projekt nicht ums \n zu kümmern und dein Code sowie die ausführbare Datei werden deutlich kleiner.

    // Entfernt, sofern vorhanden, den letzten Zeilenvorschub aus buf durch Überschreiben mit 0.
    char* remove_linefeed ( char* buf )
    {
    	char* p = strrchr ( buf, '\n' ); 
    	if ( p )
    		*p = 0; // Überschreibt den Zeilenvorschub mit 0.
    	return p;
    }
    
    int read_stdin ( char* buf, size_t bufsize )
    {
    	fgets ( buf, bufsize, stdin );
    	remove_linefeed ( buf );
    	return ferror ( stdin );
    }
    
    int main ( void )
    {  
    	char buf [ 80 ];
    	if ( read_stdin ( buf, sizeof ( buf )))
    	{
    		// Error handling ..
    	}
    	else
    	{
    		// Continue coding tidily, call slim functions ...
            process ( buf );
    	}
    
    	return 0;
    }
    


  • CJosef schrieb:

    [...]

    Ja ne, schon klar.

    Aber wer bin ich schon um mich über längst getroffene Designentscheidungen ...

    vfbf4n1893 schrieb:

    printf("Bitte geben Sie ein Wort ein, das Pr. ueberprueft, ob es sich um ein Palindrom handelt:\n");
    fgets(string, 30, stdin);
    

    ... hinwegzusetzen? ... 🤡



  • Swordfish schrieb:

    Aber wer bin ich schon um mich über längst getroffene Designentscheidungen ...
    ...
    ... hinwegzusetzen? ... 🤡

    Ja, natürlich.
    Wie konnte ich mich bloß erdreisten?! 😮
    🤡



  • Du musst vor der for Schleife dein i counter dekrementieren, da er die Länge mit '\0' angibt. Außerdem musst du nach der for Schleife dann auch das '\0' bei string2 ergänzen, da du nur den string ohne '\0' kopiert hast. Also:

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    int main()
    {
        char string[30], string2[30];
        int i=0, j=0;
    
        printf("Bitte geben Sie ein Wort ein, das Pr. ueberprueft, ob es sich um ein Palindrom handelt:\n");
        scanf("%s", string);
        printf ( "%s", string );
        while (string[++i] != '\0');
    
        i--;
        for(;i>=0;i--, j++){
            string2[j] = string[i];
        }
        string2[j] = '\0';
    
        if (strcmp(string,string2) == 0) {printf ("Palindrom");}
        else {printf("Kein Palindrom");}
        return 0;
    }
    

Anmelden zum Antworten