Brauche Hilfe bei Pointern



  • [quote="DirkB"]... unvollständiger Code[/quote]

    Habe die Funktion vervollständigt.



  • Was erwartest du dir eigentlich was der Code tun soll.



  • Eingabe in ein Array füllen (dabei stets die Grenzen einhalten) und in das Main zurückgeben.lim ist das der Puffer.
    Der vollständige Code ist im Kernighan&Ritchie.Mir geht's eigentlich darum zu sehen wie ich Array durch Pointer ersetzen.



  • Dann machst du dir, so wie du es machst, das leben schwer.
    Schau dir mal fgets an, da ist auch ein Beispiel dabei.



  • So steht's bei K&R:

    /* getline: read a line into s, return length
     */
    int getline_kr(char s[],int lim)
    {
      int c, i;
      for (i=0; i < lim-1 && (c=getchar())!=EOF && c!='\n'; ++i)
        s[i] = c;
      if (c == '\n') {
        s[i] = c;
        ++i;
      }
      s[i] = '\0';
      return i;
    }
    

    Du könntest jetzt Z. 3 ersetzen durch

    int getline_kr(char *s,int lim)
    

    und wärst fertig.

    Aber Du hast ja einiges umgestellt - welche Gedanken hast Du Dir dazu gemacht?



  • Ich weiß,eigentlich wollte ich auch fgets benutzen.Jedoch muss ich es so lösen,ist eine Vorgabe.Ich möchte es so mit Pointern machen.
    Das ist keine Hausaufgabe o.ä . Ich bin über 34 :)Ich möchte C erlernen.



  • [quote="Furble Wurble"]So steht's bei K&R:

    /* getline: read a line into s, return length
     */
    int getline_kr(char s[],int lim)
    {
      int c, i;
      for (i=0; i < lim-1 && (c=getchar())!=EOF && c!='\n'; ++i)
        s[i] = c;
      if (c == '\n') {
        s[i] = c;
        ++i;
      }
      s[i] = '\0';
      return i;
    }
    

    Du könntest jetzt Z. 3 ersetzen durch

    int getline_kr(char *s,int lim)
    

    und wärst fertig.

    Aber Du hast ja einiges umgestellt - welche Gedanken hast Du Dir dazu gemacht?[/quote]

    In dieser Version bricht es ab,sobald die Eingabe lim-1 erreicht.
    Ich wollte aber,dass es weiterzählt aber nur bis lim-1 ausgibt (lim='\0')
    Es geht ja darum,die längste Eingabe widerzugeben.Ich wollte dabei einfach nicht an lim gebunden sein.



  • Joe1903 schrieb:

    Das ist keine Hausaufgabe o.ä . Ich bin über 34 :)Ich möchte C erlernen.

    Joe1903 schrieb:

    Hallo.Ich bin neu in C und muss mich schnellstmöglich einarbeiten.

    Dass zwischen "möchte" und "muss" ein Unterschied besteht, merkste selbst, oder?

    Joe1903 schrieb:

    Ist es möglich über Email zu kommunizieren?

    Wozu? Es gibt genau überhaupt keinen Grund dafür. Tippen musst du auch so, und so können noch schlimmere Neulinge irgendwann deinen Thread finden und daraus lernen.

    D.h. wenn es Neulinge gäbe, die ihren verdammten Verstand und Suchfunktionen verwenden würden ...

    Im Übrigen verstehe ich überhaupt nicht, was du willst. Arrays durch Pointer ersetzen? Funktionen verwenden am Ende eh Adressen, und die Länge musst du so oder so mit übergeben. *

    Was zum Teufel willst du erreichen?

    EDIT: Und wenn man schon eine Größenangabe verwendet, dann nimm size_t . Das ist der größte vorzeichenfreie Typ, mit dem man noch auf deiner Plattform indizieren kann.

    EDIT 2: *Jaja, man kann auch einfach als Parameter ein Array von einer bestimmten Größe verlangen, da macht der Compiler dann den Check für einen. Es gibt Situationen, wo man das gebrauchen kann. Anfänger erkennen diese aber nicht und verwenden sie dann lieber viel zu oft. Das Gleiche mit goto . Ergibt hervorragenden Sinn, das drinzubehalten, aber Anfänger missbrauchen das gleich bis in die nächste Dimension.



  • Joe1903 schrieb:

    In dieser Version bricht es ab,sobald die Eingabe lim-1 erreicht.
    Ich wollte aber,dass es weiterzählt aber nur bis lim-1 ausgibt (lim='\0')
    Es geht ja darum,die längste Eingabe widerzugeben.Ich wollte dabei einfach nicht an lim gebunden sein.

    Aha.
    Aber wie weiss getline() , bis wohin es schreiben darf, ohne lim ?

    void f(void) {
      char s[42];
      getline(s, 42); // maximal 41 Zeichen + '\0'...mehr Platz ist nicht da!
    }
    

    PS: Hast Du BBCode in Deinen Beiträgen deaktiviert? Schalt das mal wieder an.



  • Furble Wurble schrieb:

    Joe1903 schrieb:

    In dieser Version bricht es ab,sobald die Eingabe lim-1 erreicht.
    Ich wollte aber,dass es weiterzählt aber nur bis lim-1 ausgibt (lim='\0')
    Es geht ja darum,die längste Eingabe widerzugeben.Ich wollte dabei einfach nicht an lim gebunden sein.

    Aha.
    Aber wie weiss getline() , bis wohin es schreiben darf, ohne lim ?

    void f(void) {
      char s[42];
      getline(s, 42); // maximal 41 Zeichen + '\0'...mehr Platz ist nicht da!
    }
    

    PS: Hast Du BBCode in Deinen Beiträgen deaktiviert? Schalt das mal wieder an.

    Deshalb benutze ich ja i und j als Variablen (statt nur i im Original)
    Die if-Bedingung innerhalb der for-Schleife stellt sicher,dass nur solange auf s[j] geschrieben wird,solange j>lim-1 gilt.
    i zählt hierbei die eingegeben Zeichen ohne an lim gebunden zu sein.Hoffe ich konnte ich es beschreiben.



  • Joe1903 schrieb:

    Deshalb benutze ich ja i und j als Variablen (statt nur i im Original)
    Die if-Bedingung innerhalb der for-Schleife stellt sicher,dass nur solange auf s[j] geschrieben wird,solange j>lim-1 gilt.
    i zählt hierbei die eingegeben Zeichen ohne an lim gebunden zu sein.Hoffe ich konnte ich es beschreiben.

    Also: das ist Dein Code, richtig?

    /* getline: read a line into s, return length
     */
    int getline(char *s,int lim)
    {
      int c,i,j;
      j=0;
    
      for (i=0;(c=getchar() != EOF && c != '\n');i++){
        if (j>lim-1)
          s[j++];
      }
    
      if (c == '\n'){
        if (j>lim-1)
          s[j++];
        i++;
      }
    
      s[j] = '\0';
    
      return i;
    }
    

    Was soll denn in Zeilen 9-10 und 14-16 passieren? Und was hast Du programmiert? Ich sehe überhaupt keine Zuweisungen und die Tests j>lim-1 ("größer als") sind verkehrt?

    Und allgemein verstehe ich nicht, was passieren soll? Einen String der Länge n einlesen und alle weiteren chars in der Eingabe konsumieren und verwerfen?



  • Furble Wurble schrieb:

    Joe1903 schrieb:

    Deshalb benutze ich ja i und j als Variablen (statt nur i im Original)
    Die if-Bedingung innerhalb der for-Schleife stellt sicher,dass nur solange auf s[j] geschrieben wird,solange j>lim-1 gilt.
    i zählt hierbei die eingegeben Zeichen ohne an lim gebunden zu sein.Hoffe ich konnte ich es beschreiben.

    Also: das ist Dein Code, richtig?

    /* getline: read a line into s, return length
     */
    int getline(char *s,int lim)
    {
      int c,i,j;
      j=0;
    
      for (i=0;(c=getchar() != EOF && c != '\n');i++){
        if (j>lim-1)
          s[j++];
      }
    
      if (c == '\n'){
        if (j>lim-1)
          s[j++];
        i++;
      }
    
      s[j] = '\0';
    
      return i;
    }
    

    Was soll denn in Zeilen 9-10 und 14-16 passieren? Und was hast Du programmiert? Ich sehe überhaupt keine Zuweisungen und die Tests j>lim-1 ("größer als") sind verkehrt?

    Und allgemein verstehe ich nicht, was passieren soll? Einen String der Länge n einlesen und alle weiteren chars in der Eingabe konsumieren und verwerfen?

    Sorry ja die < ist verkehrt.Also:Wenn ich im ursprünglichen Programm lim = 100 hatte (wird im Main definiert) und meine längste Eingabe z.B. 240 Zeichen hatte,gab es 2x 99 und 1x 42 aus.Und ich wollte dass es 240 ausgibt,auch wenn es den Teil nach lim verwirft.
    i zählt die Anzahl der Zeichen OHNE bei lim von vorne anzufangen.j füllt den String bis lim-1.


  • Mod

    Im ganzen Thread ist bis jetzt noch kein einziges Array aufgetaucht. Das s hier:

    int getline(char s[],int lim)
    

    Das s ist kein Array. Es ist ein Zeiger. Sieht zwar ein bisschen aus wie ein Array, weil Arrays und Zeiger eine ganz ähnliche Syntax haben, aber es ist ein Zeiger.

    Dies ist eine der wichtigsten Lektionen über C, vielleicht sogar die wichtigste, die man lernen kann. Insofern hat sich der Thread vermutlich gelohnt.



  • SeppJ schrieb:

    Im ganzen Thread ist bis jetzt noch kein einziges Array aufgetaucht. Das s hier:

    int getline(char s[],int lim)
    

    Das s ist kein Array. Es ist ein Zeiger. Sieht zwar ein bisschen aus wie ein Array, weil Arrays und Zeiger eine ganz ähnliche Syntax haben, aber es ist ein Zeiger.

    Dies ist eine der wichtigsten Lektionen über C, vielleicht sogar die wichtigste, die man lernen kann. Insofern hat sich der Thread vermutlich gelohnt.

    Auch wenn im main char s[100]; ist?



  • Wäre es nicht auch sinnvoll, das eingelesene Zeichen (im Array) abzuspeichern?



  • Zurück zu meiner ursprünglichen Frage:
    Wie kann ich bei meinem Code Array durch Zeiger ersetzen (ohne es zu ändern)?


  • Mod

    Joe1903 schrieb:

    Zurück zu meiner ursprünglichen Frage:
    Wie kann ich bei meinem Code Array durch Zeiger ersetzen (ohne es zu ändern)?

    Da ist kein Array!

    Joe1903 schrieb:

    Auch wenn im main char s[100]; ist?

    Ja. Dann zeigt der Zeiger eben auf ein Array. Er ist immer noch ein Zeiger. Eine Variable kann (in C) nicht einfach ihren Typ ändern, bloß weil die Funktion, in der sie steht, mit einem anderen Argument aufgerufen wird.



  • Sind im K&R nicht auch Beispiele für strcpy in Array- und Pointerschreibweise?
    ^Ich hab den gerade nicht zur Hand^



  • SeppJ schrieb:

    Joe1903 schrieb:

    Zurück zu meiner ursprünglichen Frage:
    Wie kann ich bei meinem Code Array durch Zeiger ersetzen (ohne es zu ändern)?

    Da ist kein Array!

    Um es nochmal ganz klar zu machen: in der main()-Funktion, bzw. in dem Scope, wo du das Array definierst, hast du ein waschechtes Array. Nur übergeben kannst du es nicht, stattdessen aber dessen Adresse, also einen Pointer auf das erste Element des Arrays. Wenn du nun in der Funktion, in dem du die Adresse des Arrays weiterreichst, auch die Größe brauchst, so gibst du als zweiten Parameter dessen Größe mit an. Arrays sind implizit in Pointer konvertierbar (aber nicht umgekehrt), das heißt aber nicht, dass ein Array ein Pointer ist! Einen Pointer jedoch kannst du genau so, wie einen Array benutzen, du kannst ihn subscripten (also mit [] ), du kannst ihn dereferenzieren (also mit * ).

    Aber bitte, behalte fest, dass ein Array kein Pointer ist. Er ist lediglich konvertierbar.



  • Joe1903 schrieb:

    Hallo.Ich bin neu in C und muss mich schnellstmöglich einarbeiten.

    Achso: einen wichtigen Punkt habe ich dann noch: aktivier Warnungen in Deinem Compiler, bzw. dreh das Warnlevel auf die empfindlichste Stufe hoch.


Anmelden zum Antworten