Blutiger Anfänger braucht Hilfe beim erstellen von Programm



  • Hallo, ich habe eine Aufgabe zu erledigen, bei der ich irgenwie nicht weiterkomme. Bin absoluter C++ Anfänger und hab kaum Ahnung.
    Und zwar soll ich ein Programm schreiben, dass einen Eingabestring einliest, alles in kleinbuchstaben umwandelt, den String umgedreht wieder ausgibt und dann auch noch auf ein Palindrom testet.

    Das ist mein Idee:

    void palindrom (char a [])
    {		
    	int length = sizeof (a) / sizeof (a[0]) //Ermittle Laenge des Strings
    	int b = 0;
    
    	for (int i = 0; i < length; i++)  //Suche Ende des Strings
    	{
    		int b = 0;
    		if (a[i] == '\0')
    		{
    			b = i;
    		}
    
    	}
    
    	int c = 0;
    	int d = 0;
    
    	for (int j = (b-1); j>=0; j--)	//Gehe String von hinten durch
    	{	                                                         
            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]);
    		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);
    	palindrom (a);
    	return 0;
    }
    

    JA das ganze funktioniert aber irgendwie nicht und ich hab absolut keine Ahnung wieso. Irgendwas hab ich wohl noch nicht so richtig verstanden. Ich darf leider keine FUnktonen aus der Standartbibliothek benutzen die den String umdreht und muss mit scanf und printf arbeiten.
    Hat irgendwer von euch eine Ahnung, warum das nicht funktioniert?



  • Dieser Thread wurde von Moderator/in SeppJ aus dem Forum C++ (auch C++0x) in das Forum C (C89 und C99) verschoben.

    Im Zweifelsfall bitte auch folgende Hinweise beachten:
    C/C++ Forum :: FAQ - Sonstiges :: Wohin mit meiner Frage?

    Dieses Posting wurde automatisch erzeugt.


  • Mod

    LilaBanane schrieb:

    Bin absoluter C++ Anfänger und hab kaum Ahnung.

    Dann ist ja gut, dass du C machst 😃 . Ich guck's mir gleich mal an, wird aber ein bisschen dauern, vermutlich ist jemand anderes schneller.



  • 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.


Log in to reply