Herzlich Willkommen, lieber Gast!
  Sie befinden sich hier:

  Forum » C / C++ (ANSI-Standard) » char Liste mit mehreren NULL-terminierten Strings füllen

Forum | Hilfe | Team | Links | Impressum | > Suche < | Mitglieder | Registrieren | Einloggen
  Quicklinks: MSDN-Online || STL || clib Reference Grundlagen || Literatur || E-Books || Zubehör || > F.A.Q. < || Downloads   

Autor Thread - Seiten: > 1 <
000
10.04.2006, 19:18 Uhr
~Rothaus
Gast


Hallo,

ich komme leider nicht auf den Trichter, einen char-Array zu basteln, in den ich mehrere (soviel wie reinpassen) NULL-terminierte Zeichenketten reinpacken kann.
Alternativ statt NULL-Terminierung auch Angabe der Zeichenketten-Länge.

Diese Problemlösung ist Teil eines Scanner-Baus und Aufgabe einer FH-Aufgabe - Programmierung in reinem C - das vorne weg. Ich möchte keine Hausaufgaben erledigt bekommen, nur eine Denkhilfe, denn ich verstehe einfach bestimmte Sachen nicht:



C++:
    const int max = 10; // size
    char* list[max]; //
    for (int i = 0; i < max; i++) {
        list[i] = NULL; // init each element with NULL
    }

    char* lexem = "Alf";
    memcpy(list, lexem + NULL, 3 + 1); // kopiere "Alf" in "list" mit anschließendem NULL-Terminator
    
    // what is inside list[] now?
    for (int k = 0; k < max; k++) {
        printf("%i: ", k);
        if (list[k] == NULL)
            printf("\n");
        else
            printf("%c\n", list[k]);
    }
    printf("As string: %s\n", list); // nach meinem Verständnis müsste das gleich sein

    lexem = "ons";
    memcpy(list + 3, lexem + NULL, 3 + 1);
    
    // what is inside list[] now?
    for (int k = 0; k < max; k++) {
        printf("%i: ", k);
        if (list[k] == NULL)
            printf("\n");
        else
            printf("%c\n", list[k]);
    }
    printf("As string: %s\n", list);


Die Ausgabe überrascht mich dann:


Code:
0: A
1:
2:
3:
4:
5:
6:
7:
8:
9:
As string: Alf
0: A
1:
2:
3: o
4:
5:
6:
7:
8:
9:
As string: Alf


Ich hätte erwartet anfangs ein "Alf [NULL] _ _ _ _ _ _" und später ein "Alfons [NULL] _ _ _" darin zu finden. Ich verstehe nichtmal, warum mir printf("%s", list) etwas anderes liefert, als meine zeichenweise Ausgabe

Wäre um jeden Tipp dankbar!
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
001
11.04.2006, 09:42 Uhr
0xdeadbeef
Gott
(Operator)


Au weia, da mischste aber einiges durcheinander...

Also, zunächst mal ist

C++:
    char* list[max];


kein char-array, sondern ein Array von Zeigern auf char. Und diese Zeiger sind im Moment alle uninitialisiert, zeigen also ins Nirvana. Ferner

C++:
    char* lexem = "Alf";


ist das hier so nicht ganz korrekt. "Alf" ist eine String-Konstante, wenn du da reinschreibst, gibt das nachher böse Probleme. Viele Compiler fressen das so, die meisten werden aber deswegen warnen. In jedem Fall ist

C++:
    char const *lexem = "Alf";


richtiger (Zeiger auf konstanten char). Allerdings ist lexem bereits null-terminiert. Im übrigen, selbst wenn

C++:
    lexem + NULL


keinen Compilerfehler verursacht, was es, denke ich, eigentlich sollte, dann wird es auf den Zeiger lexem Null draufaddieren, macht also garnichts. lexem ist ja keine Klasse wie std::string in C++, die Operatoren mit komplexen Funktionen überladen hat, sondern bloß eine Speicheradresse, also im Grunde nur eine Zahl.

Das hier:

C++:
    memcpy(list, lexem + NULL, 3 + 1); // kopiere "Alf" in "list" mit anschließendem NULL-Terminator


aus zwei Gründen Unfug, zum einen macht lexem + NULL nichts, zum anderen ist list kein char-Array. Du kopierst hier einen String in ein pointer-array, und die Pointer werden nachher irgendwo in ganz wilde Regionen zeigen.

Was die Ausgabe angeht, so wies aussieht, arbeitest du auf einer little endian 32-bit-architektur, dann ergibt das Sinn. Was passiert, ist folgendes: Ein Zeiger ist 32 bit, also 4 byte lang, ein char eins. Also sieht list nach der zweiten String-Zuweisung so aus:

Code:
|Alf\0|\0\0\0\0|\0\0\0\0|ons\0|\0\0\0\0|...


wobei \0 ein NULL-Zeichen symbolisieren soll. wenn du list jetzt als string interpretierst, gibt er die Zeichen bis zum ersten NULL-ZEichen aus, also "Alf". wenn du die Pointer einzeln als Zeichen interpretierst, nimmt er den Zeiger als Zahl, schneidet ihn auf char-Größe zurecht und gibt das Ergebnis aus - auf einer little-endian-Architektur bedeutet das, er gibt das erste Byte des Zeigers aus, also 'A' bzw. 'o'. Wichtig dabei ist, dass list + 1 hier nicht etwa genau 1 auf die Speicheradresse von list addiert, sondern ein Element im Array vorangeht, also sizeof(*list) draufgibt. *(list + 1) ist das selbe wie list[1].

Die einfachste Möglichkeit, hier heran zu gehen, ist wohl

C++:
char list[10][100];


oder so, das sind dann 10 strings a 100 Zeichen. Komplizierter wirds mit

C++:
char *list[10];
for(int i = 0; i < 10; ++i) list[i] = malloc(anzahl_benoetigter_zeichen);

// ...

for(int i = 0; i < 10; ++i) free(list[i]);


aber wenn du die Länge der Strings vorher nicht kennst, kannste da mit realloc und so halt flexibler reagieren. Ich hoffe, das hier hilft dir, viel Glück
--
Einfachheit ist Voraussetzung für Zuverlässigkeit.
-- Edsger Wybe Dijkstra
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
002
11.04.2006, 15:15 Uhr
~Rothaus
Gast



Zitat von 0xdeadbeef:
kein char-array, sondern ein Array von Zeigern auf char.


Danke, das hat mir sehr weitergeholfen
Ich denke ich habe es jetzt hinbekommen!
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
Seiten: > 1 <     [ C / C++ (ANSI-Standard) ]  


ThWBoard 2.73 FloSoft-Edition
© by Paul Baecher & Felix Gonschorek (www.thwboard.de)

Anpassungen des Forums
© by Flo-Soft (www.flo-soft.de)

Sie sind Besucher: