Hilfe bei strcat error



  • Aber sobald ich das * entferne wird das = als Fehler markiert und er sagt mir:

    Ein Wert vom Typ ""char"" kann keiner Entität vom Typ ""char *"" zugewiesen werden.

    Tut mir ja echt leid aber ich weiß beim besten Willen nicht was das bedeuten soll.



  • Warum liefert getrecht ein char und kein char*?

    Benutze std::string.



  • manni66 schrieb:

    Warum liefert getrecht ein char und kein char*?

    Benutze std::string.

    Das nützt aber nur etwas wenn er den Rest auch nach C++ umschreibt und so wie es aussieht lehrt der Lehrer C.



  • Dieser Thread wurde von Moderator/in SeppJ aus dem Forum C++ (alle ISO-Standards) in das Forum C (alle ISO-Standards) verschoben.

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

    Dieses Posting wurde automatisch erzeugt.



  • wechlol.vb schrieb:

    2. Du initialisierst visuel mit "", d.h. an erster stelle steht ein abschließendes '\0'.
    Alles was danach kommt wird von Stringverarbeitungsfunktionen nicht beachtet.

    Das ist natürlich Quatsch.
    Ein Naivling mit Helfersyndrom aber ohne Ahnung plappert irgendwas nach, was er irgendwo aufgeschnappt aber nicht verstanden hat um es anwenden zu können.

    Insbesondere ist es genau strcat, wo der Speicher nach dem String manipuliert wird.
    Die Wurzel allen Übels ist aber das Ändern von Elementen eines Stringliterals mit strcat auf visuel, das nennt man auch UB, um hier mal Ordnung in deine weitschweifigen und nicht den Kern treffenden Laien-Erklärungsversuche zu bringen.



  • Dein getrecht ist Mist.

    Als Rückgabewert hast du ein char (kann genau ein Zeichen aufnehmen).
    Bei return hast du aber ein char*. Das ist ein anderer Typ.

    Durch das fehlende free zu dem malloc produzierst du Speicherlecks ohne Ende.

    Du kannst dich an strcpy orientieren. Dort übergibst du auch den Zielstring.

    Oder du machst gleich ein Array of char*

    static char *dateirechte[] = {"---", "--x", "-w-", "-wx", .... , "rwx"};
    
    char *getrecht(int zahl) {
    
       hier Fehlerbehandlung machen;
    
       return dateirechte[zahl];
    }
    

    Für 10 Werte lohnt kein malloc .
    Du kannst auch mit Zeigern auf Arrays arbeiten.



  • DirkB schrieb:

    Dein getrecht ist Mist.

    Dazu muss ich sagen das ich noch einen Algorithmus schreiben will der diese Zeichen selbst zusammensetzt... Das sollte wesentlich kürzer und effizienter als ein switch case sein!



  • Cambaru schrieb:

    DirkB schrieb:

    Dein getrecht ist Mist.

    Dazu muss ich sagen das ich noch einen Algorithmus schreiben will der diese Zeichen selbst zusammensetzt...

    Wenn du das switch durch einen Algorithmus ersetzt, wird es nicht besser, da der switch -Teil der richtig ist (bis auf ein fehlendes break).
    Das drumherum ist Mist:

    char getrecht(int zahl) {                      // char als Rückgabetyp  
        char *vis3;
        vis3 = (char *)malloc(sizeof(*vis3) * 10); // Wo ist das free?
        ....
        return vis3;                               // Rückgabe von char*
    }
    

    Cambaru schrieb:

    Das sollte wesentlich kürzer und effizienter als ein switch case sein!

    Nicht unbedingt.
    Das switch arbeitet (intern) mit einer Sprungtabelle und muss nicht rechnen.

    Aber als Übung ist es OK.



  • Wenn du das switch durch einen Algorithmus ersetzt, wird es nicht besser, da der switch -Teil der richtig ist (bis auf ein fehlendes break).
    Das drumherum ist Mist

    Das ist inzwischen das letzte Problem welches ich habe.
    Ich habe keine Ahnung wie ich eine Funktion zu einer char* Funktion mache,falls dies überhaupt möglich ist... Beim recherchieren bin ich dabei nur auf Funktionsarten gestoßen die ich bereits kannte. 😕

    Und natürlich geht es mir nicht um Effizienz sonder nur um mir das Programmieren näher zu bringen und etwas mehr Praxis zu bekommen.

    Außerdem nochmal danke für die Antworten die ihr mir bisher gegeben habt! 👍


  • Mod

    Cambaru schrieb:

    Ich habe keine Ahnung wie ich eine Funktion zu einer char* Funktion mache,falls dies überhaupt möglich ist... Beim recherchieren bin ich dabei nur auf Funktionsarten gestoßen die ich bereits kannte. 😕

    Und natürlich geht es mir nicht um Effizienz sonder nur um mir das Programmieren näher zu bringen und etwas mehr Praxis zu bekommen.

    Das ist doch eine wunderbare Gelegenheit, richtig Programmieren zu lernen. Du scheinst gelernt zu haben, irgendwo abzuschreiben und dann zu verändern, wie man an deinem Kommentar zu "Funktionsarten" erkennen kann. Besser wäre es gewesen, wenn du gelernt hättest, wie man selber Funktionen schreibt. Und hier noch viel wichtiger, wie Zeichenketten funktionieren, so dass du weißt, wie man damit umgehen muss. Dein Lehrer scheint in dieser Hinsicht vollkommen versagt zu haben 😞

    Wir können dir hier natürlich nicht C beibringen (und merke: C hat mit C++ praktisch nichts zu tun; außer der Bedeutung verschiedener Sonderzeichen und allgemeiner Programmiererfahrung wirst du in C++ nichts von deinem C-Wissen verwenden können), aber wir können dich zumindest auf brauchbare Bücher verweisen:
    http://stackoverflow.com/questions/562303/the-definitive-c-book-guide-and-list



  • Cambaru schrieb:

    Dazu muss ich sagen das ich noch einen Algorithmus schreiben will der diese Zeichen selbst zusammensetzt... Das sollte wesentlich kürzer und effizienter als ein switch case sein!

    Bitteschön:

    #include <stdio.h>
    
    static const char perm[4] = "rwx";
    
    // Doppelt gemoppelt:
    char *getperm( char *vis, int num )
    {
    //	printf( "num: %d\n", num );
    
    	for( int i = 0; i < 3; ++i )
    		vis[i] = (num & (4 >> i)) == 4 >> i ? perm[i] : '-';
    
    	return vis;
    }
    
    int main( void )
    {
    	char vis[4] = "eop";
    	puts( getperm( vis, 3 ) ); // puts( vis );
    	puts( getperm( vis, 6 ) ); // puts( vis );
    	puts( getperm( vis, 5 ) ); // puts( vis );
    	puts( getperm( vis, 7 ) ); // puts( vis );
    	return 0;
    }
    


  • Bevor mir da irgendwelche Klagen kommen, bitte

    num &= 7;
    

    an passender Stelle einfügen.



  • Oder:

    #include <stdio.h>
    
    char *getperm( char *vis, int num )
    {
    
    printf( "%d = ", num );
    
    	for( int i = 0; i < 3; i++ )
    		vis[i] = (num & 4 >> i) != 4 >> i ? '-' : i ? 'r'+4+i : 'r';
    
    	return vis;
    }
    
    int main( void )
    {
    	char vis[4] = "eop";
    	for( int i = 0; i < 8; ++i )
    		puts( getperm( vis, i ) );
    
    	return 0;
    }
    

  • Mod

    Du kannst übrigens auch direkt Zeichenkettenliterale dereferenzieren. Kein Grund, dafür einen globalen Bezeichner einzuführen:

    "rwx"[i]
    

    Oder für Extra-Obfuscation:

    i["rwx"]
    

    PS: Das ganze Problem des TE ist mit der gleichen Technik natürlich auf

    const char *getperm(int num )
    {
     static const char* perms[] = {"---", "--x", "-w-", "-wx", "r--", "r-x", "rw-", "rwx"};
     return perms[num];
    }
    

    oder in C99 gar auf

    return (const char*[]){"---", "--x", "-w-", "-wx", "r--", "r-x", "rw-", "rwx"}[num];
    

    reduzierbar.



  • Neumodischer Kram! Ich hab 1989 C gelernt (noch ohne C89 Standard damals).
    Ausserdem hat es mir heute Nacht nach 1 l Wein, 4 Halbe Bier und 3 Schnäpsen einfach Spaß gemacht 4-2-1 und 0-1-2 mit nur einer Variablen in eine Beziehung zu bringen. Und verschwurbelt sollte es natürlich auch aussehen. 🙂



  • So ich habs endlich geschafft...
    Alles was ich wollte funktioniert nun!
    Danke für eure Hilfe!!!!

    #define _CRT_SECURE_NO_WARNINGS
    #include <stdio.h>
    #include <stdlib.h>
    #include <time.h>
    #include <string.h>
    
    const char *getperm(int num)
    {
    	static const char* perms[] = { "---", "--x", "-w-", "-wx", "r--", "r-x", "rw-", "rwx" };
    	return perms[num];
    }
    
    int randrecht(){
    	int rnum;
    	rnum = rand()%7;
    	return rnum;
    }
    
    int main(void){
    	srand(time(NULL));
    	char zeichen[2]={};
    	char visuel[10]={};
    	char *vergleich;
    	/*visuel = (char *)malloc(sizeof(*visuel) * 10);*/
    	vergleich = (char *)malloc(sizeof(*vergleich) * 10);
    	int eingabe;
    	int rnum;
    	int i,e;
    
    	printf("Linux-Rechte Test\n");
    	do{
    		printf("Wählen sie zwischen folgenden Möglichkeiten:\n");
    		printf("1.Test Starten\n");
    		printf("2.Beenden\n");
    		scanf("%d", &eingabe);
    
    		//generiert eine 3 stellige zufalls-zahl
    		printf("Gib die rechte für die Zahl: ");
    		for (i = 0;i < 3;i++) {
    			rnum = randrecht();
    			printf("%d", rnum);
    			strcpy(zeichen,getperm(rnum));
    			strcat(visuel,zeichen);
    		}
    		printf(" ein!\nBsp: r-xrw----\n");
    		//vergleicht antwort mit lösung
    		do {
    			scanf("%s",vergleich);
    			e = strcmp(vergleich, visuel);
    
    		} while (e != 0);
    		//ausgabe
    		printf("Eingabe korrekt\n");
    		system("pause");
    		system("cls");
    	}while(eingabe == 1);
    
    	free(vergleich);
    	free(zeichen);
    	free(visuel);
    }
    


  • Cambaru schrieb:

    So ich habs endlich geschafft...
    Alles was ich wollte funktioniert nun!
    Danke für eure Hilfe!!!!

    Ist aber falsch:

    int main(void){
    
    	srand(time(NULL));
    	char zeichen[2]={};
    	char visuel[10]={};
    	char *vergleich;
            vergleich = (char *)malloc(sizeof(*vergleich) * 10);
    ....	
    	free(vergleich); // OK
    	free(zeichen);   // ergibt UB
    	free(visuel);    // ergibt UB
    }
    

    Bei UB kann nichts passieren oder Fehlermeldung oder Systemcrash oder Katzentot oder Weltkrieg oder ...



  • Hallo Camburu!

    Wenn du mehrere Zufallszahlen hintereinander generierewn willst dann
    ist es besser eine globale Varialbe zu definieren, mit der
    du feststellen kannst ob die Funktion srand() bereits einmal
    gestartet wurde.
    Diese darf nur einmal gestartet werden im Proggi, sonst erhältst du immer
    die selben Werte. Im folgenden Beispiel ist die globale Variable initrandom,
    welche mit dem Wert Null initialisiert wird.

    int initrandom = 0;
    

    Diese Zeile würde dann in deinem Code vor randrecht() stehen

    danach kommt zum Beispiel folgende Funktion:

    //generiert Zufallszahlen von 1 bis 32767;
    int getrand (int lowerlimit, int toprange)
    {
    // bis 32767
     //srand (time (NULL));
     if (initrandom == 0)
      {
      srand (time (NULL));
      initrandom = 1;
      }
     return (rand () % (toprange + 1)) + lowerlimit;
    }
    

    mit der du Zufallzahlen von >=lowerlimit bis <= toprange generierst.

    bei

    //generiert Zufallszahlen von 1 bis 32767;
    int getrand (int lowerlimit, int toprange)
    {
    // bis 32767
     //srand (time (NULL));
     if (initrandom == 0)
      {
      srand (time (NULL));
      initrandom = 1;
      }
     return (rand () % toprange ) + lowerlimit;
    }
    

    sind es Zufallszahlen von >=lowerlimit bis < toprange.

    Übrigens kann man Zeichenfolgen, sofern diese aus einem
    eindimensionalen Array bestehen, auf wie folgt ändern:

    void getrecht(int zahl, char ergebnis[]) {
        //wandelt zahlen in visuelle zeichen
     int i;
     char vis[8][5] = {"---", "--x", "-w-", "-wx", "r--", "r-x", "rw-", "rwx" };
       for (i = 0; i <= 3; i++)
        ergebnis [i] = vis[zahl][i];
    
    }
    

    Bei dem Parameter 2 handelt es sich um ein eindimensionales Array.
    Diese kannst du praktisch in einer Funktion direkt manipulieren, anders
    als bei anderen Variablentypen, das liegt daran, wie die Adressen der
    Variable, wenn es sich um Arrays des Typs char handelt, übergeben werden.
    Aus dem Grund brauchst du auch keinen Adressoperator bei der scanf-Funktion
    angeben, falls du einen String als Variable hast, bei anderen, wie etwa
    int brauchst du das "&"-Zeichen davor.



  • rustyoldguy schrieb:

    Wenn du mehrere Zufallszahlen hintereinander generierewn willst dann ist es besser eine globale Varialbe zu definieren, mit der
    du feststellen kannst ob die Funktion srand() bereits einmal
    gestartet wurde.

    Fröstel, fröstel, rustyoldguy. Quite rusty, quite questionable.


Anmelden zum Antworten