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 demmalloc
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 derswitch
-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.
Dasswitch
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 MistDas 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!
-
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; }
-
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.