Inhalt eines char Pointers konvertieren
-
char **PtrNamPtrArr = NULL; int i = NamAnz; PtrNamPtrArr = (char**) malloc((sizeof(char*)*i)+(sizeof(char)*MAXANZ*i)); char *buffer = (char*)(PtrNamPtrArr+(sizeof(char*)*i)); if(PtrNamPtrArr){ while(i--){ PtrNamPtrArr[i] = (buffer+i*((sizeof(char)*MAXANZ))); } i=NamAnz; while(i--){ fgets(PtrNamPtrArr[i],MAXANZ,stdin); PtrNamPtrArr[i][strlen(PtrNamPtrArr[i])-1] = '\0'; } i=NamAnz; while(i--){ printf(PtrNamPtrArr[i]); } }
Hab das jetzt so angepasst, dass es nicht sofort abstürzt ((char**) vor malloc) und angepasst, dass man Anfangs eine Zahl (NamAnz) eingibt, die die Anzahl der einzutragenden Namen steuert. Problem ist er lässt mich nur NamAnz-1 eintragen, den letzten Namen nimmt er einfach als leer mit. Ansonsten blicke ich den Code auch nicht wirklich durch, falls du den etwas erklären könntest wär das super!
-
also ich hatte mir das so vorgestellt, gehen wir mal von dem alten teil aus
char *xxx[10];
das heißt wir brauchen speicher für 10 zeiger auf einen string, und dann brauchen wir noch speicher für die strings, in oberem fall hat jeder string eine unterschiedliche länge das ist aber jetzt erstmal gleich, also hab ich einfach mal 256 als länge genommen, dann hätte man 2 möglichkeiten das zu lösen erstechar **PtrNamPtrArr = NULL; //wir holen uns speicher für ein array mit 10 char* zeiger PtrNamPtrArr = malloc(sizeof(char*)*10); //jetzt haben wir speicher für unser array aber keinen speicher für die //strings, den brauchen wir auch also... int l=10; while(l--){ PtrNamPtrArr[l] = malloc(sizeof(char)*256); } //und jetzt haben wir alles was wir brauchen das ist eigentlich die saubere //variante und das sollte man auch so machen, wir brauchen aber jetzt 11*malloc //und das wollte ich mir schenken indem ich mir mit einem malloc den speicher //in einem stück hol und mir das dann selbst aufteil
die zweite variante hast ja schon;)
-
#include <stdio.h> #include <stdlib.h> #include <string.h> int main(void) { char **PtrNamPtrArr = NULL; int nameLength = 255; int arrayLength = 10; int i = arrayLength; char *buffer;//könnte man auch weglassen da es sich nicht ändert //malloc castet man nur in c++ da bist aber im falschen unter forum;) //wir holen uns den gesamten speicher für die strings und das array PtrNamPtrArr = malloc( (sizeof(char*) * arrayLength) +(sizeof(char) * arrayLength * nameLength) ); if(PtrNamPtrArr != NULL){ buffer = (char*)(PtrNamPtrArr+sizeof(char*) * arrayLength); //buffer zeigt jetzt auf den ersten wert nach dem array //jetzt weisem wir dem array den speicher für die strings zu while(i--){ PtrNamPtrArr[i] = (buffer + i * (sizeof(char) * nameLength)); } i=arrayLength; while(i--){ fgets(PtrNamPtrArr[i],nameLength-1,stdin); //fgets nimmt '\n' mit das machen wir wieder weg... PtrNamPtrArr[i][strlen(PtrNamPtrArr[i])-1] = '\0'; } i=arrayLength; while(i--){ printf(PtrNamPtrArr[i]); } } }
weiß nicht ob dir das weiter hilft aber ich weiß auch nicht wie ich das erklären soll
-
Wenn ich den Malloc nicht caste, bekomme ich aber folgenden Fehler:
Error 7 error C2440: '=' : cannot convert from 'void *' to 'char *[]'
Bei der Zeile:
NamPtrArr = malloc( (sizeof(char*) * arrayLength) +(sizeof(char) * arrayLength * nameLength) );
Wenn ich den Malloc (char**) caste kompiliert es. Aber das Problem, dass wenn ich 3 Namen eingeben will, nur 2 eintragen kann, bleibt.
-
Etwas das ich jetzt absolut nicht nachvollziehen kann:
Anzahl der Namen: 3 01Timo 2Katze 3Hund 01Timo2Katze3Hund Ausgabe 1: Namen in Original-Reihenfolge und Original-Schreibweise Name 1: Name 2: Timo Name 3: Katze weiter mit [return]:
Ist die (nachträglich formatierte Ausgabe von folgendem Code)
int nameLength = MAXANZ; int arrayLength = NamAnz; int i; char *buffer;//könnte man auch weglassen da es sich nicht ändert //malloc castet man nur in c++ da bist aber im falschen unter forum;) //wir holen uns den gesamten speicher für die strings und das array PtrNamPtrArr = (char**) malloc((sizeof(char*)*arrayLength)+(sizeof(char)*arrayLength*nameLength)); if(PtrNamPtrArr != NULL){ buffer = (char*)(PtrNamPtrArr+sizeof(char*) * arrayLength); //buffer zeigt jetzt auf den ersten wert nach dem array //jetzt weisem wir dem array den speicher für die strings zu for(i = 0; i <= arrayLength; i++){ PtrNamPtrArr[i] = (buffer + i * (sizeof(char) * nameLength)); } for(i = 0; i <= arrayLength; i++){ printf("%d", i); fgets(PtrNamPtrArr[i],nameLength,stdin); //fgets nimmt '\n' mit das machen wir wieder weg... PtrNamPtrArr[i][strlen(PtrNamPtrArr[i])-1] = '\0'; } for(i = 0; i <= arrayLength; i++){ printf("%d", i); printf(PtrNamPtrArr[i]); } }
Und ich verstehe einfach nicht, wieso er das erste fgets einfach nicht ausführt, sondern überspringt?
-
also bei mir klappts schon würde allerdings in den for schleifen < statt <= schreiben?
nameLength = ist der länge des namens
arrayLength = die anzahl an namen
-
achso und in z.18 hatte ich nameLength-1 weil ich verhindern wollte das jemand meine letzte 0 überschreiben kann...
-
Ich kann tun was ich will, das erste fgets überspringt er/ignoriert er, keine Ahnung was er macht. Und ich kann mir nicht erklären wieso. Egal ob ich jetzt <= in den for-Schleifen oder < mache. Die Namen dürfen maximal 50 Zeichen lang sein, das haben wir mit einer #define MAXANZ auf 51 oben schon geklärt und NamAnz wird beim Programmstart von der Tastatur per scanf eingelesen.
Wenn ich jetzt 3 in NamAnz eingebe, dann startet die Eingabe-Schleife und gibt, statt auf eine Eingabe von fgets zu warten, sofort 0 und 1 aus. Also im Schleifendurchlauf in dem i = 0 ist, wartet fgets nicht auf eine Parametereingabe, sondern springt einfach weiter. Das Programm wartet erst bei i = 1 auf eine Namenseingabe. Dadurch hab ich insgesamt 4 Namen, von denen der erste leer ist und nur die letzten 3 eingegeben sind. Aber der Array muss ja von 0 an aufgefüllt sein.
Keine Ahnung wie das weitergeht jetzt.
-
ich bin überfragt? aber es hängt nicht evtl. damit zusammen dass du dein '\n' nach dem scanf, nicht abholst, sonst würde das da noch warten und dann beim ersten fgets abgeholt werden ohne eingabe?
versuch mal einfach ein getchar() nach dem scanf() die rückgabe von getchar() kannst einfach verwerfen...
[quote] NamAnz wird beim Programmstart von der Tastatur per scanf eingelesen./quote]
-
Aaaah, ja klar. Nach dem Scanf wurde der Eingabepuffer ja nicht geleert. Hm. Gut, jetzt wird das erste fgets angesprochen und trägt auch die Namen irgendwo ein.
Merkwürdigerweise kriege ich nun allerdings einen neuen Fehler, der mich darauf schließen lässt, dass irgendetwas nicht richtig gespeichert ist:
void OutNamen(char *KopfText, char *NamPtrArr[], int NamAnz) { char dummy[81]; //clrscr(); printf ("%s\n\n", KopfText); for (int i = 0; i < NamAnz; i++) { printf("Name %2d: %s\n", i+1, NamPtrArr[i]); } printf("\nweiter mit [return]:"); gets(dummy); }
Diese Funktion ist dazu da, um die Namen nach jedem Schritt an den Bildschirm auszugeben. Die Zeile "printf("Name %2d: %s\n", i+1, NamPtrArr[i]);" wird mir allerdings mit folgender Fehlermeldung angezeigt, sobald ich Namen eingegeben habe:
An unhandled exception of type 'System.NullReferenceException' occurred in pa4.exe
Additional information: Object reference not set to an instance of an object.
-
-
das kann doch garnicht sein sonst würde ja das hier
PtrNamPtrArr[i][strlen(PtrNamPtrArr[i])-1] = '\0';
auch nicht klappen?
-
Innerhalb der Funktion GetNamen() kann ich auch alles per printf() ausgeben.
Zurück in Main() oder in der Ausgabe-Funktion OutNamen() allerdings wiederum nicht. Ich schätze, dass irgendwie das Array falsch übermittelt wird, oder falsch abgespeichert oder sonstwas. Ich hab wirklich keine Ahnung.
void OutNamen(char *KopfText, char *NamPtrArr[], int NamAnz) { char dummy[81]; //clrscr(); printf ("%s\n\n", KopfText); for (int i = 0; i < NamAnz; i++) { printf("Name %2d: %s\n", i+1, NamPtrArr[i]); } printf("\nweiter mit [return]:"); gets(dummy); }
void GetNamen(char *NamPtrArr[], int NamAnz) { int nameLength = MAXANZ; int arrayLength = NamAnz; int i; char *buffer;//könnte man auch weglassen da es sich nicht ändert //malloc castet man nur in c++ da bist aber im falschen unter forum;) //wir holen uns den gesamten speicher für die strings und das array NamPtrArr = (char**) malloc((sizeof(char*)*arrayLength)+(sizeof(char)*arrayLength*nameLength)); if(NamPtrArr != NULL){ buffer = (char*)(NamPtrArr+sizeof(char*) * arrayLength); //buffer zeigt jetzt auf den ersten wert nach dem array //jetzt weisem wir dem array den speicher für die strings zu for(i = 0; i < arrayLength; i++){ NamPtrArr[i] = (buffer + i * (sizeof(char) * nameLength)); } for(i = 0; i < arrayLength; i++){ printf("Name %2d: ", i+1); fgets(NamPtrArr[i],nameLength,stdin); //fgets nimmt '\n' mit das machen wir wieder weg... NamPtrArr[i][strlen(NamPtrArr[i])-1] = '\0'; } for(i = 0; i < arrayLength; i++){ printf("%d", i); printf(NamPtrArr[i]); } } printf("\n\nweiter mit [return]:"); }
int main(void) { char **PtrNamPtrArr = NULL; int NamAnz = 0; //char *TstNamPtrArr[10] = { "hans", "FRANZ", "oTTo", "lisa-marie", "LISA MARIE" }; //int NamAnz = 5; printf("Anzahl der Namen: "); scanf("%d", &NamAnz); getchar(); printf("\n\n"); GetNamen(PtrNamPtrArr, NamAnz); OutNamen("Ausgabe 1: Namen in Original-Reihenfolge und Original-Schreibweise", PtrNamPtrArr, NamAnz); ConvertNamen(PtrNamPtrArr, NamAnz); OutNamen("Ausgabe 2: Namen in Original-Reihenfolge mit korrigierter Schreibweise", PtrNamPtrArr, NamAnz); SortNamen(PtrNamPtrArr, NamAnz); OutNamen("Ausgabe 3: Namen alphabetisch aufsteigend sortiert", PtrNamPtrArr, NamAnz); }
-
versuch mal sowas
char **GetNamen(char *NamPtrArr[], int NamAnz) { statt void GetNamen(char *NamPtrArr[], int NamAnz) { natürlich am ende der GetNamen funktion return NamPtrArr; und PtrNamPtrArr = GetNamen(PtrNamPtrArr, NamAnz); statt GetNamen(PtrNamPtrArr, NamAnz);
-
btw. hab mal gehört, sowas
scanf("%d", &NamAnz); getchar(); printf("\n\n");
macht man nur wenn man was zu verstecken hat
und solltest du nach sloc bezahlt werden schießt dir selbst ins bein...
-
sollte mein vorheriger post klappen kannst auch
char **GetNamen(int NamAnz) { char *NamPtrArr[] ..... statt char **GetNamen(char *NamPtrArr[], int NamAnz) { .....
machen
-
So funktioniert jetzt alles. Nur leider sind die Unterprogrammköpfe ebenfalls in der Aufgabenstellung vorgegeben. Das heißt die müssen void sein.
-
Kuh-Couch schrieb:
Nur leider sind die Unterprogrammköpfe ebenfalls in der Aufgabenstellung vorgegeben.
ich hab schon gewußt wieso ich solche zettel nicht leiden konnte
dann mach alles bis auf
for(i = 0; i < arrayLength; i++){ printf("Name %2d: ", i+1); fgets(NamPtrArr[i],nameLength,stdin); //fgets nimmt '\n' mit das machen wir wieder weg... NamPtrArr[i][strlen(NamPtrArr[i])-1] = '\0'; }
aus der function raus und packs in main() oder eine eigene function createArray() oder so wenn das erlaubt ist, sonst machst ihm ne monster main
jeder wie er es haben will...
das problem ist dass du der function einen NULL pointer übergibst und dieser dann mit speicher gefüllt wird, wird die function beendet steht da wieder NULL drin d.h. du mußt der function einen pointer != NULL übergeben
-
Die Main dürfen wir zuklatschen wie wir wollen, MIT DER AUSNAHME, dass wir außer PtrNamPtrArr und NamAnz keine Variablen zu Programmstart definiert haben dürfen. Das heißt wenn du jetzt auch noch eine Methode hast, wie wir das ganze ohne
char *buffer;
in der Main lösen können, wäre uns super geholfen.
-
buffer = (char*)(NamPtrArr+sizeof(char*) * arrayLength); //buffer zeigt jetzt auf den ersten wert nach dem array //jetzt weisem wir dem array den speicher für die strings zu for(i = 0; i < arrayLength; i++){ NamPtrArr[i] = (buffer + i * (sizeof(char) * nameLength)); }
na dann
for(i = 0; i < arrayLength; i++){ NamPtrArr[i] = ((NamPtrArr+sizeof(char*) * arrayLength) + i * (sizeof(char) * nameLength)); }
evtl. muß da noch der ein oder andere cast rein evtl. so??
for(i = 0; i < arrayLength; i++){ NamPtrArr[i] = (((char*)(NamPtrArr+sizeof(char*) * arrayLength)) + i * (sizeof(char) * nameLength)); }
na dann mal viel spaß damit