getline() wird vom compiler nicht erkannt



  • Vielen Dank, sehr hilfreich!

    werd es mal probieren, also zeichen solange einlesen bis \n kommt und notfalls puffer-array vergrößern.

    Nur noch eine allerletzte frage für heute:

    wie prüfe ich, ob das array voll ist?
    mir fällt da nur die möglichkeit ein einen counter mitzählen zu lassen und immer zu vergleichen, ob länge des arrays erreicht ist, wisst ihr was besseres?

    Vielen Dank nochmals!



  • jay186 schrieb:

    wie prüfe ich, ob das array voll ist?
    mir fällt da nur die möglichkeit ein einen counter mitzählen zu lassen und immer zu vergleichen, ob länge des arrays erreicht ist, wisst ihr was besseres?

    Was besseres wird dir bei "arrays" via malloc()/realloc() auch nicht einfallen.

    PS: "arrays" in Hochkomma, weil man in C zwischen echten arrays und Zeigern auf Speicher (via malloc() etc) unterscheiden muss. Link: http://c-faq.com/aryptr/aryptr2.html (und folgende)



  • Gut, Danke.

    Falls ich das nicht hinkriegen sollte, weiß ich ja wo ich Hilfe bekomme.

    Vielen Dank nochmals!
    (man kann sich nicht oft genug für freiwillige hilfe bedanken)



  • 18.16.3 <- Das tut weh.



  • ich hab' das hier in meiner 'grabbelkiste' gefunden:

    char *readline (void)
    {
        char *s, *p = 0;
        int c, n = 0;
    
        for (;;)
        {
            if (n%512 == 0)
            {
                p = realloc (p, n+512);
                s = p;
            }
            c = getchar();
            if (c == '\n')
            {
                s[n] = 0;
                break;
            }
            s[n++] = c;
        }
        return p;
    }
    

    sieht so aus, wie das, was du brauchst.
    (fehlertest beim realloc fehlt)
    🙂



  • Hey Danke für den code!

    Folgende Fragen hätte ich trotzdem:

    1. Warum ist im schleifenkopf der for schleife nichts drin?

    2. Warum brauche ich 2 pointer s und p?

    3. Warum wird n%512==0 üperprüft, woher kommen die 512?

    4. c ist ein int wert, warum kommen da char's rein? (ich muss zahlen von einer datei einlesen, d.h. ich müsste mit atoi() und strtok() den string noch in zahlen umwandeln, aber jetzt wird in ein char array int-werte gespeicehrt, warum?



  • 5. wenn n größer als 512 wird, dann wird kein neuer speicher mehr alloziert, da n%512 dann ungleich 0 ist und irgendwann wenn n bei 1025 ist wird das "array" überschritten, oder nicht?



  • jay186 schrieb:

    1. Warum ist im schleifenkopf der for schleife nichts drin?

    Weil es so praktischer ist.

    Die Schleife läuft so lange bis '\n' eingegeben wird. Das in den Kopf zu packen würde die komplexität des Codes ein bisschen erhöhen. Deshalb nimmt er einfach eine "endlosschleife" und baut an der richtigen Stelle ein "break" ein um die Schleife zu beenden.

    2. Warum brauche ich 2 pointer s und p?

    In dem Code nicht. Erst wenn du einen Fehler bei realloc abfangen willst brauchst du 2 Zeiger. Den realloc würde dir s mit 0 überschreiben wenn es fehlschlägt und dein Speicher wäre weg.

    3. Warum wird n%512==0 üperprüft, woher kommen die 512?

    Frei erfunden. Es werden gerne 2er Potenzen genommen für Blockgrößen. Der Speicher in dieser Funktion wächst immer um 512 Bytes. Eine uU sinnvollere Strategie wäre ein *2 jedesmal. Im Prinzip ist die Zahl hier aber nur ein Schätzwert.

    4. c ist ein int wert, warum kommen da char's rein? (ich muss zahlen von einer datei einlesen, d.h. ich müsste mit atoi() und strtok() den string noch in zahlen umwandeln, aber jetzt wird in ein char array int-werte gespeicehrt, warum?

    Fehler im Code. EOF zeigt an wenn die Datei (oder in diesem Fall die Eingabe) zuende ist. zB wenn man eine Datei an das Programm piped. EOF kann aber kein char sein weil es nicht darstellbar ist. Deshalb ist EOF ein int und c muss daher ein int sein wenn man auf EOF testen will. Dieser Test fehlt im Code.

    5. wenn n größer als 512 wird, dann wird kein neuer speicher mehr alloziert, da n%512 dann ungleich 0 ist und irgendwann wenn n bei 1025 ist wird das "array" überschritten, oder nicht?

    n%512 ist 0 wenn n 0, 512, 1024,... ist. Jedesmal wenn das eintritt, wird das Array um 512 Elemente vergrößert.

    % liefert ja den Rest einer Division. Und alle vielfachen von 512 sind restlos durch 512 teilbar.

    Es fehlt in dem Code ein n+=512.



  • das hab ich mir mal überlegt:

    char *puffer = NULL;
    unsigned int counter = 0;
    size_t t = 1000;
    
    puffer = calloc(t, sizeof(char));
    
    while (true) {
         if (c = fgetc(FILE)) == "/n")
              break;
         else if (counter > "letzter Index des Arrays"){
              t=2*t;
              puffer = realloc(puffer,t);
              puffer[counter++] = c;}
         else puffer[counter++] = c;
    }
    


  • danke nochmals für die erläuterungen, werde wohl den vorgeschlagenen code nehmen!

    Noch ne Frage:

    was passiert wenn die letzte Zeile kein newline hat? was kann man da tun?



  • Es heisst '\n' und nicht "/n" und du hast EOF vergessen. Weiters hast du keine Fehlerüberprüfung wenn realloc/calloc fehlschlagen.

    EOF ist auch die Lösung des Problems wenn es kein \n gibt. fgetc liefert dir in so einem Fall EOF wenn er das Zeichen nach dem letzten liest.



  • okay danke! denke dass ich es jetzt hinbekommen.

    noch eine frage:

    was steht am Ende im "array"? integerwerte oder stringfolge?
    kann ich also strtok() auf das "array" anwenden?



  • jay186 schrieb:

    okay danke! denke dass ich es jetzt hinbekommen.

    noch eine frage:

    was steht am Ende im "array"? integerwerte oder stringfolge?
    kann ich also strtok() auf das "array" anwenden?

    Wenn es ein char* ist, stehen chars drinnen.

    In C ist alles ein string was aus chars besteht und am Ende den Wert '\0' stehen hat.



  • der int c wird also in ein char gecastet.
    woher kommt aber beim einlesen das "/0"?



  • jay186 schrieb:

    okay danke! denke dass ich es jetzt hinbekommen.

    noch eine frage:

    was steht am Ende im "array"? integerwerte oder stringfolge?
    kann ich also strtok() auf das "array" anwenden?

    Am Ende eines Strings Arrays muss eine 0 (das \0-Zeichen) stehen, sonst ist es keine C-String und die Funktionen von string.h liefern ein undefiniertes Verhalten.

    edit: uups, ein bisschen zu spät 😡

    jay186 schrieb:

    der int c wird also in ein char gecastet.
    woher kommt aber beim einlesen das "/0"?

    nur die erten 8 Bits kommen rein, bei normalen Zeichen (Buchstaben) kein Problem. Das \0 Zeichen musst du selber reintun, wenn du Zeichen für Zeichen liest. Und es heißt \0, \n, usw, mit einem Backslash.

    Hier mein Code 😉 (Achtung, ungetestet)

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    void *inc_memory(void *ptr, size_t *act_size, size_t new_size)
    {
        if(*act_size < 2*new_size + 1)
        {
            /* no data loss if realloc returns NULL */
            ptr = realloc(ptr, 2*new_size+1); 
    
            if(ptr == NULL)
                return NULL;
    
            *act_size = 2*new_size+1;
        }                
    
        return ptr;      
    }                    
    
    char *get_next_line(char *buff, FILE *fp)
    {
        char *tmp;
        int c;
        size_t len = 0, new_len = 0, pos = 0;
    
        while( ((c=fgetc(fp)) != '\n') && ( c != EOF ) && !feof(fp))
        {
            new_len++;
            tmp = inc_memory(buff, &len, new_len);
            if(tmp == NULL)
            {
                printf("inc_memory returns NULL\n");
                free(buff);
                return NULL;
            }
    
            buff = tmp;
            buff[pos] = c;
            buff[++pos] = 0;
        }                               
    
        return buff;
    }
    
    int main(void)                      
    {
        char *line = NULL;
    
        line = get_next_line(line, stdin);
    
        if(line == NULL)
        {
            fprintf(stderr, "Shit\n");
            return 1;
        }
    
        printf("Eingabe: \"%s\"\n", line);
    
        free(line);
    
        return 0;
    }
    


    /* no data loss if realloc returns NULL */
            ptr = realloc(ptr, 2*new_size+1); 
    
            if(ptr == NULL)
                return NULL;
    

    wo wird hier ptr gesichert?

    2. was passiert hier:

    !feof(fp)
    

    und

    3. warum

    if(*act_size < 2*new_size + 1)
    

    2*x+1?



  • benötigt man die #include <string.h>?
    ich darf nur die c Standardbibltiothek nutzen...



  • Die string.h gehört zur Standardbibliothek.



  • void *inc_memory(void *ptr, size_t *act_size, size_t new_size)
    

    Warum wird size_t new_size nicht per call-by-reference üebrgeben, size_t *act_size aber schon?



  • Shade Of Mine schrieb:

    Es fehlt in dem Code ein n+=512.

    brauch nicht, die zeile s[n++] = c; macht das.
    🙂


Anmelden zum Antworten