Blutiger Anfänger braucht Hilfe beim erstellen von Programm



  • Als erstes must du uns schon sagen, was da genau nicht funktioniert. Mit einem "irgendwie" kann man nicht viel anfangen.
    Welchen Einschränkungen unterliegt denn die Aufgabe? Darfst du std::strings verwenden? Wenn ja, dann würde ich dir auch zu diesen raten.
    Sag bloß nicht, dass ihr C++ lernen sollt.

    P.S. Immerhin hast du als "blutiger, ahnungsloser Anfänger" einen (den Umständen entsprechend) besseren oder zumindest saubereren Code zusammengestrickt als so manche "Erfahrene".



  • Was genau funktioniert denn nicht?

    Das Einlesen eines Strings ist schonmal falsch. Das Ganze machst du mit

    char my_string[1024];
    scanf("%s", my_string);
    

    Das %i, was du benutzt kenn ich gar nicht. Was soll das für ein Format sein?

    Schau mal hier: http://www.cplusplus.com/reference/clibrary/cstdio/scanf/

    Da stehen alle Formatcodes zusammengefasst da.

    Ob deine Routine richtig ist hab ich jetzt nicht geschaut.
    Um das zu testen geb doch einfach mal den String mit

    printf("Das wurde eingelesen: %s", my_stringf);
    

    aus. Dann siehst du ob das Einlesen geklappt hat.



  • überigens, es gibt einen Befehl in C, der dir das mühsame Grosse Zeichen in Kleine Zeichen umwandeln abnimmt: tolower();
    Ende Des Strings lässt sich mitt strlen() eleganter lösen.



  • Binggi schrieb:

    überigens, es gibt einen Befehl in C, der dir das mühsame Grosse Zeichen in Kleine Zeichen umwandeln abnimmt: tolower();

    Ich glaube, es ist der Sinn der Aufgabe, dass sie das selber implementieren.
    Das (Zeile 9)

    int b = 0;
    

    wird immer in dem Scope bleiben, das heißt: sobald du den Codeblock verlässt, bekommt b wieder den Wert 0. Lösung: lösche die Zeile.

    Wozu braucht du denn b , wenn du length schon hast?

    Dann:

    if ((a[c] <= 90) && (a[c] >= 65))
            {
                a[c]+=32;                         
            }
    

    Wozu brauchst du das denn? Damit gehst du den String von hinten und vorne durch. Brauchst nicht.

    printf ("%i", a[j]);
    

    meintest du hier wieder %s?


  • Mod

    #include <string.h>
    #include <ctype.h>
    #include <stdio.h>
    #include <stdbool.h>
    
    void palindrom (char a [])
    {		
      // int length = sizeof (a) / sizeof (a[0]) 
      // Gut abgeguckt, funktioniert aber nicht. Das gibt dir nur die Größe eines Pointers. Richtig:
    
      int length = strlen(a);
    
      /*  int b = 0;
    
          for (int i = 0; i < length; i++)  //Suche Ende des Strings
          {
           int b = 0;
           if (a[i] == '\0')
            {
             b = i;
            }
          }
      */
      // Das Ende kennst du doch schon! Es ist bei a[length-1]
    
      /*	int c = 0;
    	int d = 0;
      */
      // Gib deinen Variablen mal lesbare Namen, anstatt alphabetisch durch zu gehen
    
      bool ist_palindrom = true;
    
      for (int index_vorne = 0; index_vorne < length; ++index_vorne)	// Ich mag lieber vorwärts zählen
        {	                                                         
          //      if ((a[j] <= 90) && (a[j] >= 65))				
          //      Selbst wenn dies hier nötig wäre, schreib lieber a[j] >= 'A' anstatt 
          //      magische Zahlen wie 65 zu benutzen.
          //
          //      Aber es geht sowieso viel einfacher:
          a[index_vorne] = tolower(a[index_vorne]);
          int index_hinten = length-1-index_vorne;
          a[index_hinten] = tolower(a[index_hinten]);
          if(a[index_vorne]!= a[index_hinten]) //Testen auf Palindrom
            {
              ist_palindrom = false;
            }
    
          printf ("%c", a[index_hinten]);
        }
    
      printf ("\n");
    
      if (ist_palindrom)
        {
          printf ("String ist Palindrom \n");
        }
    }
    
    int main ()
    {
      char a [1024];
      printf ("Bitte geben Sie ein Wort ein: ");
      if (scanf ("%1023s", a) != EOF)
        palindrom (a);
      return 0;
    }
    


  • Tja, wie sag ichs...

    Da rund die Hälfte meiner Vorposter Deine Frage und die Aufgabenstellung entweder nicht gelesen oder nicht verstanden haben, hoffe ich mal, mich nicht mit einzureihen...

    Edit: SeppJ war schneller 🙂

    Richtig an den Antworten war bisher: Du verwendest mehr Variablen als nötig und der "Formatstring" für Deine Eingabefunktion ist wahrscheinlich der größte Knackpunkt am Code.

    Ungetestet und aus meiner Phantasie entstammend:

    void c2up (char *c) // Wenn Kleinbuchstabe, umwandeln. Sonst nicht.
    {
       if (*c <= 90 && *c >= 65)
          *c+=32;
    }
    void palindrom (char *str) // Habe ich jetzt mal ganz dreist zum Pointer gemacht
    {                          // Dadurch bleiben änderungen am "String" für die aufrufende Funktion erhalten
        int length, i;
    
        for (length = 0; str[length]; length++);
        //length wird hochgezählt, bis str[length] == 0; 
        //bei 10 Zeichen wäre length 10; 
        //der letzte char in str, der nicht 0 ist, wäre der mit dem index 9...
    
        int pal = 1;
        int c = length;
        int d = -1;
        while ( c >= d )
        {
           c2up (str[--c]);
           c2up (str[++d]);
           if (str[c] == str[d])
              continue;
           pal = 0;  // wird nur erreicht, wenn kein palindrom
        }
        printf ("\n");
        if (pal)
            printf ("String ist Palindrom \n");
        else
            printf ("String ist kein Palindrom \n");
    }
    
    int main ()
    {
        char a[1024];
        printf ("Bitte geben Sie ein Wort ein: ");
        if (scanf ("%1023s",a) != EOF)
        {
           printf ("Vor der Funktion palindrom:\n-> %s\n", a);
           palindrom (a);
           printf ("Nach der Funktion palindrom:\n-> %s\n", a);
        }
        return 0;
    }
    


  • Dann definier noch

    int tolower_(int c)
    {
    return (c+32*(c>='A' && c<='Z'));
    }
    int strlen_(const char *str) 
    { 
            const char *s; 
            for (s = str; *s; ++s); 
               return (s - str); 
    }
    

    Dann hat dein Lehrer auch freude 😉

    EDIT: PrettyC war schneller...



  • void palindrom (char a [])
    {       
        int length = sizeof (a) / sizeof (a[0]) //Wie schon gesagt, ermittle einfacher mit strlen()
        int b = 0; //¹Initialisiere deine Variabeln vorerst alle mal am Anfang
    
        for (int i = 0; i < length; i++) // Wie gesagt ist dieser Bereich besser durch strlen() ersetzt
    
        {
            int b = 0; // Deklaration wohl nicht sinnvoll, da im Gültigkeitsbereich nicht lesend zugegriffen wird => Siehe ¹
            if (a[i] == '\0')
            {
                b = i;
            }
    
        }
    
        int c = 0;
        int d = 0;
    
        for (int j = (b-1); j>=0; j--)    //b ist hier 0 => Schleife wurde nei durchlaufen
        {                                                             
            if ((a[j] <= 90) && (a[j] >= 65))               
            {                // Abfrage ob große Buchstab
            a[j] += 32;         // Umwandeln in kleine Buchstaben
            }
    
            if ((a[c] <= 90) && (a[c] >= 65))
            {
                a[c]+=32;                         
            }
    
            if(a[j]!= a[c])            //Testen auf Palindrom
            {
                    d += 1;
            }
    
            printf ("%i", a[j]); //was wird das? Wie wärs mit %c?
            c++;
        }
    
        printf ("\n");
    
        if (d==0)
        {
            printf ("String ist Palindrom \n");
        }
    }
    
    int main ()
    {
        char a [1024];
        printf ("Bitte geben Sie ein Wort ein: ");
        scanf_s ("%i", & a); //wieso willst du Wörter als eine Zahl einlesen. Funktioniert das mit der scanf_s eigentlich auch mit %i? Verwende lieber %s.
        palindrom (a);
        return 0;
    }
    


  • Binggi schrieb:

    ...
    return (c+32*(c>='A' && c<='Z'));
    ...
    

    Diese 32 sollten da auch noch weg. ('a'-'A')



  • DirkB schrieb:

    Binggi schrieb:

    ...
    return (c+32*(c>='A' && c<='Z'));
    ...
    

    Diese 32 sollten da auch noch weg. ('a'-'A')

    oder sogar

    return((unsigned char)(c) - 'A' + 'a');



  • return((unsigned char)(c) - 'A' + 'a');
    

    Passt aber nicht.
    Damit würde ein 'a' etc. kein 'a' etc. bleiben



  • DaRe schrieb:

    return((unsigned char)(c) - 'A' + 'a');
    

    Passt aber nicht.
    Damit würde ein 'a' etc. kein 'a' etc. bleiben

    Hast recht. Mein Fehler.


Anmelden zum Antworten