Anzeige:
Ergebnis 1 bis 14 von 14

Thema: newbie - strings

  1. #1
    Registrierter Benutzer
    Registriert seit
    15.07.2000
    Ort
    D 55118 Mainz
    Beiträge
    25

    Question newbie - strings

    Moin,

    kann mir jemand sagen, wie ich einen Text in einen String packen kann?

    BSP:
    char var1[] = " ";

    var1[] = "schnick schnack";


    Bei diesem Versuch ernte ich vom Compiler parse error before ']'

    DasSein
    http://dassein.tripod.com/start.html









    DasSein sagt: Good vibes for everyone, also da people I don't like.











    Mein System:





    AMD K6 III 400





    512KB L2 Cache





    128MB SDRAM





    ATI Rage II Grafik





    Creative Vibra 16 Sound





    3Com 905b Combo





    Teledat 150 ISDN





    Mitsumi 40x CD Rom





    Yamaha CW2100E 16x CD RW



    Debian Potato 2.2r3

  2. #2
    Registrierter Benutzer
    Registriert seit
    10.04.2001
    Ort
    Bremen
    Beiträge
    339

    Post

    Hier ein Beispiel:

    char *test;
    test="hallo";

    cu,
    Tobias

  3. #3
    Registrierter Benutzer
    Registriert seit
    21.01.2001
    Beiträge
    157

    Post

    Wenn es doch ein array und kein Pointer sein soll, dann hilft strcpy.

    Code:
    char s[20];
    strcpy(s, "Hello world!");
    Hierbei ist aber zu beachten, dass genuegend Speicherplatz fuer das Array reserviert wurde.
    Besser ist noch strncpy, da damit moegliche buffer overflows vermieden werden koennen.

    Code:
    char s[20];
    strncpy(s, "Hello world!", 19);
    s[19] = 0;
    Und nicht vergessen: das abschliessende Nullbyte braucht auch Speicher und sollte nicht fehlen ;-)

  4. #4
    Registrierter Benutzer
    Registriert seit
    15.07.2000
    Ort
    D 55118 Mainz
    Beiträge
    25

    Cool

    Wow, das ging ja fix. Vielen Dank.
    http://dassein.tripod.com/start.html









    DasSein sagt: Good vibes for everyone, also da people I don't like.











    Mein System:





    AMD K6 III 400





    512KB L2 Cache





    128MB SDRAM





    ATI Rage II Grafik





    Creative Vibra 16 Sound





    3Com 905b Combo





    Teledat 150 ISDN





    Mitsumi 40x CD Rom





    Yamaha CW2100E 16x CD RW



    Debian Potato 2.2r3

  5. #5
    Registrierter Benutzer
    Registriert seit
    15.07.2000
    Ort
    D 55118 Mainz
    Beiträge
    25

    Question

    Aber eine Frage hätt ich ja doch noch.
    Was wär denn da der Unterschied, wenn ich einen array definiere oder einen Zeiger verwende?

    DasSein
    http://dassein.tripod.com/start.html









    DasSein sagt: Good vibes for everyone, also da people I don't like.











    Mein System:





    AMD K6 III 400





    512KB L2 Cache





    128MB SDRAM





    ATI Rage II Grafik





    Creative Vibra 16 Sound





    3Com 905b Combo





    Teledat 150 ISDN





    Mitsumi 40x CD Rom





    Yamaha CW2100E 16x CD RW



    Debian Potato 2.2r3

  6. #6
    Registrierter Benutzer
    Registriert seit
    10.04.2001
    Ort
    Bremen
    Beiträge
    339

    Post

    Hi!
    Also... Vorweg sei erstmal gesagt das ich gerade C lerne . Kann also falsch sein. ABer soweit ich das jetzt auswendig weiss, kannst du mit einem zeiger auf ein char unendlich lange strings speichern. Berichtigt mich bitte, wenn ich falsch liege.

    cu,
    Tobias

  7. #7
    stiviman
    Gast

    Talking

    hi

    den parse error krigst du weil du "keinem" element im array einen wert zuweist.
    var1[0]='a'; würde gehn
    var1[]='a'; geht nicht;-)


    unterschied zwischen array und zeiger:
    wenn du ein array deklarierst:
    char var1[10];
    werden ab irgendeiner speicherstelle genau 10 bytes fürs array reserviert.
    bei einem pointer:
    char *var2;
    werden nur platz für den pointer reserviert.

    mit var2 = "hallo\0"; legst du den string hallo im speicher an und lässt var2 darauf zeigen
    mit var1[0]="hallo\n"; weist du dem nullten Element (dass genau ein Byte lang ist) eine speicheradresse zu! (die 4 bytes lang ist) das geht nicht;-)
    es würde funktionieren wenn du ein char * array machen würdest ( char *var1[])
    es würde kurioserweise auch funktionieren wenn du ein integer-array machen würdest, da ein integer 4 bytes lang ist!!!

    jaja, c ist interessant;-)

    wir nehmen an die adresse für
    char var1[10]; ist 20.
    die speicheradresse für
    char *var2; ist 40
    die speicheradresse (anfang) des strings
    "hallo\0" ist 60

    Befehl:
    var2 = "hallo\0";
    Wirkung:
    Speicheradresse von var2: immer noch 40
    Speicheradresse von String: immer noch 60
    Inhalt von var2 (Speicheradresse 40): jetzt 60

    Befehl:
    var1[0] = "hallo\0";
    Speicheradresse von var1[0]: immer noch 20
    Speicheradresse von String: immer noch 60
    Inhalt von var1 (Speicheradresse 20): -112
    Weil: var1 ein chararray ist und pro element nur 1 byte erlaubt sind.
    somit ist das erste byte der zahl 60 als var1[0] abgespeichert... zwar kompliziert, aber so ist es.

    Und deshalb gibts auch einen speicherzugriffsfehler wenn du versuchst, dass auszugeben, weil es die adresse -112 nicht gibt.
    beim kompillieren würdest allerdings noch mit einem warning davon kommen;-)

    hinweis zum verstehen:
    warum muss man ein char array bei strcpy verwenden?
    syntax: strcpy(var1, "hallo");
    in der funktion wird der string "hallo" zeichen für zeichen in var1 kopiert. die funktion macht also grob folgendes:

    var1[0]='h';
    var1[1]='a';
    ...
    var1[5]='\0';

    deshalb muss es ein array sein. und deshalb ist es nicht so gut wenn dass array zB nur 3 elemente hätte, da strcpy nicht überprüft ob genug platz ist. in so einem fall entsteht ein buffer-overflow (oder ein speicherzugriffsfehler)

    ---------------------------
    das wars;-)
    tschau

  8. #8
    Registrierter Benutzer
    Registriert seit
    15.07.2000
    Ort
    D 55118 Mainz
    Beiträge
    25

    Cool

    Moin moin,

    ich hab zwar nicht alles verstanden, aber ein Stück weiter bin ich nu schon. Vielen Dank.

    Also noch mal zum Verständnis. Auf arrays kann demnach nur über seine Indizes zugefgriffen werden, ich dachte mir sowas schon.
    Und dieser Bufferoverflow entsteht, wenn ich nun versuche in den array mehr Zeichen reinzuschieben, als er aufnehmen kann. Dem kann ich aber entgegenwirken, wenn ich strncpy() verwende?.

    Diese Geschichte mit den Speicheradressen habe ich noch nicht so ganz geschnallt. Was heisst, die Speicheradresse von var1[10] ist 20 und die anderen 40 und 60. Wie muss ich das verstehen? Nehmen wir an ich hätte 100 Kästchen (Matheheft). Den char array mache ich zehn Zeichen lang, also mit Nullbyte am Ende 11 Kästchen; eine int variable wäre also 4 Kästchen lang? Wäre dann das erste Kästchen des arrays auf der 20. Stelle?

    Irgendwie verstehe ich auch nicht wie da jetzt eine -112 zustande kommt?
    http://dassein.tripod.com/start.html









    DasSein sagt: Good vibes for everyone, also da people I don't like.











    Mein System:





    AMD K6 III 400





    512KB L2 Cache





    128MB SDRAM





    ATI Rage II Grafik





    Creative Vibra 16 Sound





    3Com 905b Combo





    Teledat 150 ISDN





    Mitsumi 40x CD Rom





    Yamaha CW2100E 16x CD RW



    Debian Potato 2.2r3

  9. #9
    stiviman
    Gast

    Post

    es geht darum: dass ist momentan noch nicht so wichtig, und auch nicht schlimm wennstes noch nicht so ganz verstehst. aber eins is ganz leicht zu kapieren:

    ein char ist (per definition in linux) genau 1 BYTE lang.
    ein int ist (per definition in linux) genau 4 BYTE lang. (ich glaub sogar 8, aber weis nicht genau, jedenfalls mehr als ein char!)

    ( es gibt nen operator sizeof. den kannst anwenden auf irgendeine variable. der gibt dir die anzahl der reservierten bytes zurück. also sizeof(int) würde 4 ergeben. sizeof(char) ergibt 1 usw...

    ein array "arbeitet" nicht byte für byte, sondern eher element für element.
    du hast jetzt dein matheheft und fängst links oben beim ersten kästchen zum zahlen an.
    deklarierst du ein int-array, werden im matheheft sizeof(int) * AnzahlElemente Kästchen(Bytes) reserviert.
    machst du dass zb so:
    int i[9]; werden 4*10 Kästchen reserviert, also 40 (4* 10 deshalb, da ja mit 0 zu zählen begonnen wird)
    bei
    char c[9]; werden 1*10 Kästchen reserviert, also 10 (sizeof(char) = 1)
    zu den kästchen:
    nehmen wir an das array beginnt im matheheft(im speicher) beim 1. kästchen. wenn das ein chararray ist, und du aufs 5. element zugreifst (also c[4]), dann greifst du auf das 5. kästchen zu. (4 und 5 deshalb, da man beim array ja mit 0 zu zählen beginnt)
    machst du das ganze mit nem int-array (also i[4]) greifst du auf das 20. kästchen zu. (5*4 -> 5. element, sizeof(int) = 4)

    und alles andere is eh unwichtig

  10. #10
    Registrierter Benutzer
    Registriert seit
    15.07.2000
    Ort
    D 55118 Mainz
    Beiträge
    25

    Post

    Ah jetzt, ja. Eine Insel.

    Und der Zeiger char *var zeigt dann auf die erste Stelle des eigentlichen strings, wobei ich mir um ihm vorher keine Gedanken machen muss, wie gross er nacher tatsächlich ist? Heisst das, das bei dieser Variante kein Bufferoverflow entstehen kann?

    Und dann hätt' ich noch eine andere Frage. Den Bereich, den ein Programm zur Laufzeit zur Speicherung von Variablen verwendet ist der Stack. 1. Wie gross ist der unter C? Bei Turbo Pascal damals waren es 64kb. 2. Stimmt es, dass die Werte, auf die pointer zeigen, ausserhalb des Stack liegen?

    Als dann, bye.

    DasSein
    http://dassein.tripod.com/start.html









    DasSein sagt: Good vibes for everyone, also da people I don't like.











    Mein System:





    AMD K6 III 400





    512KB L2 Cache





    128MB SDRAM





    ATI Rage II Grafik





    Creative Vibra 16 Sound





    3Com 905b Combo





    Teledat 150 ISDN





    Mitsumi 40x CD Rom





    Yamaha CW2100E 16x CD RW



    Debian Potato 2.2r3

  11. #11
    Registrierter Benutzer
    Registriert seit
    21.01.2001
    Beiträge
    157

    Post

    kleine Korrektur, aber wichtig:
    int i[9] reserviert 9 ints, also 9*4 Bytes und nicht 10 * 4 Bytes.

    Ansprechbar als i[0] bis i[8]

  12. #12
    stiviman
    Gast

    Post

    ups, natürlich werden nur soviele elemente reserviert wie angegeben sind;-)) (aber wenn man so viel schreibt....*g*)
    ich halte mich jetzt zurück:
    @flasheye: da du strcpy bei char * praktisch nicht anwendest können auch keine overflows entstehen
    wie groß der stack ist weis ich nicht, bis jetzt hat er immer gereicht;-)

  13. #13
    Registrierter Benutzer
    Registriert seit
    21.01.2001
    Beiträge
    157

    Post

    Ueber die theoretischen Grenzen des Stacks unter linux solltst Du dir keine Sorgen machen. Praktisch hast Du soviel Stack zur verfuegung wie freien Speicher (inklusive Swap)

    Nochmal ein paar Klarstellungen.
    Alle Variablen die am Anfang einer Funktion deklariet werden, werden auf dem Stack gespeichert.
    Fuer alle globalen Variablen wird beim Programmstart der Speicherplatz reserviert und mit Nullbytes gefuellt (nicht Stack).
    Fuer alle Stringkonstanten ("Hello World!"+Nullbyte) die im Quelltext vorkommen wird aehnlich wie bei den globalen Variablen der Speicherplatz beim Programmstart reserviert und mit den Texten gefuellt.

    Weiterer Speicher kann dynamisch mit malloc() angefordert und mit free() wieder freigegeben werden. (nicht Stack)

    Ein Pointer/Zeiger speichert die Adresse einer anderen Variablen. Dabei ist es egal ob diese statisch alloziiert wurde, auf dem Stack liegt oder mit malloc und free reserviert wurde.
    Ein Pointer kann ja auch ungueltige Adressen speicherm, was dann halt zu Programmfehler fuehrt.

    Solange ich von einem gueltigem Pointer lese, brauche ich mir keine Gedanken ueber overflows zu machen.
    Aber sobald ich in den Speicher schreibe muss ich immer sicherstellen, das an dieser Adresse auch genuegend Speicher reserviert wurde.

    [code]
    int main(){
    char s[10];
    char *p1="Hello world!";
    char *p2="123456789"
    char *p3;

    // p1 und p2 zeigen jeweils auf statisch allozierte Strings
    // p3 enthalt irgeneinen wert, wahrcheinlich ein ungueltiger Pointer
    // s hat platz fuer 10 Zeichen (einschliesslich Nullbyte), d.h. Strings mit 9 sichtbaren Zeichen
    p3=p2; // Nur die Adresse wird kopiert, no problems
    p2="weiter"; // p2 wird die Adresse des statisch (vor dem Programmstart) alloziertem und initialsiertem "weiter" uebergeben
    // p1 Zeigt immer noch auf "Hello Wolrd!"
    // p2 zeigt auf "weiter"
    // p3 zeigt auf "123456789
    strcpy(s,p2); // Die Zeichenfolge "weiter" + Nullbyte wird in das Array s kopiert
    strcpy(s,p3); // Die Zeichenfolge "123456789" + Nullbyte wird in das Array s kopiert
    p2=s; // Die (Start)Adresse des Arrays s wird in p2 gespeichert, p2 ziegt auf den Inhalt von s, momentan "123456789" + Nullbyte ('\0')
    strcpy(s,p1); // Buffer overflow, da "Hello world!" + Nullbyte laenger als 10 Zeichen ist.
    p2=(char*)malloc(100); // Es wird Platz fuer 100 Zeichen reserviert und die Adresse in p2 gespeichert
    // Falls kein Speicher mehr frei ist, wird NULL zurueckgeliefert
    strcpy(p2,p1); // Die Zeichenkette "Hello wolrd!" +Nullbyte wird in den reservierten Speicher kopiert

    // wenn wir den speicher nicht mehr brauchen geben wir in wieder frei
    free(p2); // Achtunf ab jetzt nicht mehr auf den Speicher zugreifen, auf den p2 zeigt, da er uns nichtmehr gehoert (SEGMENTATION FAULT wahrscheinlich)


    }

  14. #14
    Registrierter Benutzer
    Registriert seit
    15.07.2000
    Ort
    D 55118 Mainz
    Beiträge
    25

    Thumbs up

    Auch hier ein dickes Lob jgbaumann, vielen Dank.
    http://dassein.tripod.com/start.html









    DasSein sagt: Good vibes for everyone, also da people I don't like.











    Mein System:





    AMD K6 III 400





    512KB L2 Cache





    128MB SDRAM





    ATI Rage II Grafik





    Creative Vibra 16 Sound





    3Com 905b Combo





    Teledat 150 ISDN





    Mitsumi 40x CD Rom





    Yamaha CW2100E 16x CD RW



    Debian Potato 2.2r3

Lesezeichen

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •