tutorials.de Buch-Aktion 05/2012
ERLEDIGT
JA
ANTWORTEN
12
ZUGRIFFE
486
EMPFEHLEN
  • An Twitter übertragen
  • An Facebook übertragen
AUF DIESES THEMA
ANTWORTEN
  1. #1
    DarKo87 DarKo87 ist offline Mitglied
    Registriert seit
    Nov 2007
    Beiträge
    15
    Moin,

    Ich versuche gerade Zeilenweise aus einer Datei zu lesen.
    Dies mache ich ganz einfach mit

    Code :
    1
    
    while((line_val=getline(&line_ptr, t, datei)) != EOF)

    Nun möchte ich jede Zeile in einen Char schreiben, damit ich diesen danach zerlegen kann.
    Aber irgendwie möchte nichts klappen.

    Kann mir vielleicht jemand ne hilfestellung geben?

    Gruß DarKo
     

  2. #2
    deepthroat deepthroat ist offline Mitglied Diamant
    tutorials.de Premium-User
    Registriert seit
    Jun 2005
    Beiträge
    8.168
    Hi.

    So wie du das machst ist das grundlegend falsch. Das dürfte auch überhaupt nicht kompilieren, bzw. was für eine getline Funktion soll das denn sein?
    Code cpp:
    1
    2
    
    while (::std::getline(datei, string)) {
    }
    Gruß
     
    If at first you don't succeed, try again. Then quit. No use being a damn fool about it.

  3. #3
    DarKo87 DarKo87 ist offline Mitglied
    Registriert seit
    Nov 2007
    Beiträge
    15
    Code :
    1
    
    while((line_val=getline(line_ptr, t, datei)) != EOF)

    Code :
    1
    2
    
    size_t *t = malloc(0);
    line_ptr = malloc(sizeof(char*));

    Seh da eigentlich kein Problem bei mir, line_val gibt die zeilen länge ohne \n an.
    ich brauche line_ptr keine länge anzugeben, weil es sich je nach länge der Zeile selbst
    verlängert.
     

  4. #4
    deepthroat deepthroat ist offline Mitglied Diamant
    tutorials.de Premium-User
    Registriert seit
    Jun 2005
    Beiträge
    8.168
    Aha, du hast dir also eine eigene getline Funktion geschrieben? Wie sieht die aus? Was ist line_ptr?

    Und du verwendest C? Warum nimmst du dann nicht einfach fgets?
    Zitat Zitat von DarKo87 Beitrag anzeigen
    Code :
    1
    
    while((line_val=getline(line_ptr, t, datei)) != EOF)

    Code :
    1
    2
    
    size_t *t = malloc(0);
    line_ptr = malloc(sizeof(char*));

    Seh da eigentlich kein Problem bei mir
    Dafür sehe ich welche...

    sizeof(char*) ist immer konstant und ziemlich klein - die Größe eines Zeigers halt. Du solltest evtl. Speicher für einen String allozieren.

    Zitat Zitat von DarKo87 Beitrag anzeigen
    ich brauche line_ptr keine länge anzugeben, weil es sich je nach länge der Zeile selbst
    verlängert.
    Dann müßtest du aber die Adresse von line_ptr übergeben. Oder verwendest du doch C++ und Referenzen?

    Zeig deinen Code.

    Gruß
     
    If at first you don't succeed, try again. Then quit. No use being a damn fool about it.

  5. #5
    DarKo87 DarKo87 ist offline Mitglied
    Registriert seit
    Nov 2007
    Beiträge
    15
    Okay mein Fehler, habe gerade gelesen wenn man getline(*ptr, *n, *stream) [*ptr = NULL, *n = NULL] übergibt die länge der Zeile übernimmt. Ich verwende C.

    Meine Funktion soll ganz einfach die ausgelesene Zeile komplett in ein Char schreiben.
    Damit ich diesen Char übergeben kann.


    Code :
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    
    /********************* function definitions *******************************/
    /***************************************************************************
    * @NAME: t_read
    * @FUNC: read all lines in open file*
    *
    ***************************************************************************/
     
    void *t_read (void){
     
     
        int8_t v_mutex, i;
     
        size_t *t = 0;
        line_ptr = NULL;
     
        v_mutex = pthread_mutex_lock(&dataMutex);
        while((line_val=getline(line_ptr, t, datei)) != EOF){
            //Send line to char
            pthread_cond_broadcast(&dataPresentCondition);
            pthread_cond_wait(&dataPresentCondition, &dataMutex);
        }
     
        pthread_mutex_unlock(&dataMutex);
        return 0;
    }
     

  6. #6
    deepthroat deepthroat ist offline Mitglied Diamant
    tutorials.de Premium-User
    Registriert seit
    Jun 2005
    Beiträge
    8.168
    Zitat Zitat von DarKo87 Beitrag anzeigen
    Okay mein Fehler, habe gerade gelesen wenn man getline(*ptr, *n, *stream) [*ptr = NULL, *n = NULL] übergibt die länge der Zeile übernimmt.
    Wie bitte?
    Zitat Zitat von DarKo87 Beitrag anzeigen
    Ich verwende C.
    Aha. Schau mal hier wie man die getline Funktion verwendet: http://linux.die.net/man/3/getline
    Zitat Zitat von DarKo87 Beitrag anzeigen
    Meine Funktion soll ganz einfach die ausgelesene Zeile komplett in ein Char schreiben.
    Was ist Char? Ein typedef? Meintest du char? -> das wäre aber nur ein Zeichen...
     
    If at first you don't succeed, try again. Then quit. No use being a damn fool about it.

  7. #7
    DarKo87 DarKo87 ist offline Mitglied
    Registriert seit
    Nov 2007
    Beiträge
    15
    Also die Funktion macht jetzt das was sie soll.
    Jede Zeile wird komplett ausgelesen, egal wie lang sie ist.

    In line_val steht die länge der Zeile.
    Mit memcpy kann ich die komplette Line in den char kopieren der mit einer länge l[256] definiert wurde.

    Is doch richtig oder? Weil Funktionieren tuts


    Code :
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    
     
    char  **line_ptr;
    char l[256];
     
    void *t_read (void){
        
        int8_t v_mutex;
     
        size_t t = malloc(0);
        line_ptr = malloc(sizeof(char*));
     
        v_mutex = pthread_mutex_lock(&dataMutex);
        while((line_val=getline(line_ptr, t, datei)) != EOF){
            memcpy(&l, *line_ptr, 256);
            broadcast();
            pthread_cond_wait(&dataPresentCondition, &dataMutex);
        }
     
        pthread_mutex_unlock(&dataMutex);
        return 0;
    }
     

  8. #8
    deepthroat deepthroat ist offline Mitglied Diamant
    tutorials.de Premium-User
    Registriert seit
    Jun 2005
    Beiträge
    8.168
    Zitat Zitat von DarKo87 Beitrag anzeigen
    In line_val steht die länge der Zeile.
    Mit memcpy kann ich die komplette Line in den char kopieren der mit einer länge l[256] definiert wurde.
    Du solltest nicht versuchen mehr Daten zu kopieren als vorhanden sind. In line_val steht die Länge der Zeile.
    Zitat Zitat von DarKo87 Beitrag anzeigen
    Is doch richtig oder?
    Nein, nicht wirklich.

    Warum schaust du dir denn nicht mal den Beispielcode an? Und achtest auf die Warnungen (-Wall einschalten!) des Compilers?

    Gruß
     
    If at first you don't succeed, try again. Then quit. No use being a damn fool about it.

  9. #9
    Avatar von Bratkartoffel
    Bratkartoffel Bratkartoffel ist offline gebratene Kartoffel
    tutorials.de Premium-User
    Registriert seit
    Jun 2007
    Ort
    Passau (Niederbayern)
    Beiträge
    1.394
    Hi,

    hier noch ein paar Voschläge von mir, wie ich das machen würde:

    * v_mutex (zeile 7) brauchst du nicht, ausserdem liefert pthread_mutex_lock() laut doku einen int zurück, keinen int8_t.
    * warum initialisiert du "t" mit malloc(0)? Würde auch den Namen von "t" anpassen, so dass das ganze mnemonischer wird.
    * warum machst du nen pointer auf ein char*?
    * weshalb ist deine Funktion mit einem Rückgabetyp "void*" deklariert, obwohl du nur "0" zurücklieferst?
    * ich würde nur so viele Daten kopieren, wie auch gelesen wurden, also die Variable "t" (oder bei mir "len") verwenden.
    * du allozierst für line_ptr Speicher, den du in der Funktion nicht mehr frei gibst. Speicherleck?

    Hier mal mein Vorschlag, mit Kommentaren:
    Code c:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    
    #define INIT_BUFFER_SIZE 256
    char* line = NULL;
     
    int t_read(void) {
        /* zeile vorbereiten und Speicher reservieren */
        if(line == NULL) {
            line = (char*) malloc(sizeof(char) * INIT_BUFFER_SIZE);
            if(line == NULL) {
                errno = ENOMEM;
                return -1;
            }
        }
        
        /* länge des puffers speichern */
        size_t len = INIT_BUFFER_SIZE;
     
        /* mutex sperren */
        pthread_mutex_lock(&dataMutex);
        
        /* errno zurücksetzen */
        errno = 0;
        
        /* zeilenweise die daten lesen */
        while(getline(&line, &len, datei) != -1) {
            if(errno != 0) {
                /* fehler beim lesen, siehe doku von getline.
                 * wenn die funktion hier verlassen wird, sollte noch "line"
                 * per free() freigegeben werden */
            }
     
            /* broadscast */
            broadcast();
            
            /* pthread_cond_wait */
            pthread_cond_wait(&dataPresentCondition, &dataMutex);
        }
        
        /* mutex entsperren */
        pthread_mutex_unlock(&dataMutex);
        
        /* allozierten speicher freigeben */
        free(line);
        line = NULL;
        
        /* erfolg melden */
        return 0;
    }

    // Edit: Das ganze von mir ist ungetestet direkt aus meinem Kopf raus und hat noch keinen Compiler gesehen

    Gruß
    BK
    Geändert von Bratkartoffel (16.11.11 um 18:12 Uhr)
     
    Über eine gute Bewertung freut sich jeder ;)
    Bitte erledigte Threads als "Erledigt" markieren.

    "Though a program be but three lines long, someday it will have to be maintained.''
    -- Geoffrey James, "The Tao of Programming"

  10. #10
    DarKo87 DarKo87 ist offline Mitglied
    Registriert seit
    Nov 2007
    Beiträge
    15
    Danke erst einmal für die hilfe Ich bin noch in der Ausbildung und in der HMI hat leider nicht immer jeder Zeit für mich Aber fehler sind ja da um daraus zu lernen :-D

    Zitat Zitat von Bratkartoffel Beitrag anzeigen
    * v_mutex (zeile 7) brauchst du nicht, ausserdem liefert pthread_mutex_lock() laut doku einen int zurück, keinen int8_t.
    Also v_mutex benutze ich damit ich den übergabe wert von mutex_lock prüfen kann.
    Theoretisch könnte ich das dann so auch direkt an die Funktion übergeben.
    Code :
    1
    
    c_value(pthread_mutex_lock(&dataMutex));

    Code :
    1
    2
    3
    4
    5
    6
    
    void c_value(uint16_t value){
     
        if(value==1){
            exit(1);
        }
    }

    Brauche also tatsächlich kein v_mutex.

    * warum initialisiert du "t" mit malloc(0)? Würde auch den Namen von "t" anpassen, so dass das ganze mnemonischer wird.
    * warum machst du nen pointer auf ein char*?
    Ähm ja, also ich richte mich ein wenig nach dem Buch. C von A bis Z, ist nicht das beste, aber es hilft doch irgendwie. Kann also nicht ganz erklären warum der Autor das ganze auf malloc(0) setzt :-/ Aber malloc(0) ist ja eigentlich das gleiche wie NULL, oder?

    Der Pointer auf char* ( so hab ich es verstanden ) erweitert sich selbst. Das bedeutet das es sich den Speicher nimmt was es braucht. Und char* ist ja 16 lang ... und durch den Pointer wird es immer wieder um 16 größer ... hmm, oder denk ich nun falsch?

    * weshalb ist deine Funktion mit einem Rückgabetyp "void*" deklariert, obwohl du nur "0" zurücklieferst?
    Das ist ganz einfach ... damit eclipse aufhört zu meckern! Ohne Return, gibt der mir meistens Warnings aus. Daher hau ich einfach nen return 0; unten dran. Stören tuts eigentlich nicht, weil nen rückgabe wert gibts ja auch eigentlich nicht, schlicht nur speicher verschwendung.

    Das Programm steckt noch in den Kinderschuhen Ich hab die Funktionen noch nicht ganz ausgearbeitet, es fehlen ja auch noch die Fehler Meldungen. Die ich noch ausarbeiten muss.

    Best regards DarKo87
    Geändert von DarKo87 (17.11.11 um 08:02 Uhr)
     
    Dieser Beitrag und sein Inhalt sind Geistiges Eigentum von DarKo87

    Mit freundlichen Grueßen / Best regards

    DarKo87

  11. #11
    deepthroat deepthroat ist offline Mitglied Diamant
    tutorials.de Premium-User
    Registriert seit
    Jun 2005
    Beiträge
    8.168
    Zitat Zitat von DarKo87 Beitrag anzeigen
    Ähm ja, also ich richte mich ein wenig nach dem Buch. C von A bis Z, ist nicht das beste, aber es hilft doch irgendwie.
    Ja, das sieht man wie es "hilft"
    Zitat Zitat von DarKo87 Beitrag anzeigen
    Kann also nicht ganz erklären warum der Autor das ganze auf malloc(0) setzt :-/ Aber malloc(0) ist ja eigentlich das gleiche wie NULL, oder?
    Genau. Aber warum sollte man eine Funktion aufrufen um eine Variable auf NULL zu setzen?
    Zitat Zitat von DarKo87 Beitrag anzeigen
    Der Pointer auf char* ( so hab ich es verstanden ) erweitert sich selbst. Das bedeutet das es sich den Speicher nimmt was es braucht. Und char* ist ja 16 lang ... und durch den Pointer wird es immer wieder um 16 größer ... hmm, oder denk ich nun falsch?
    Ein C Zeiger ist in der Regel auf einer 32bit Maschine 32bit, also 4 Byte groß, auf 64bit dann 8 Byte.

    Von vornherein einen char** zu verwenden ist eigentlich nur unnütz kompiliziert. Aus der Manpage von getline:
    Code c:
    1
    2
    3
    
    char *line = NULL;
    size_t len = 0;
    getline(&line, &len, ...);
    Ein char** erweitert sich nicht von selbst. Die getline Funktion tut dies - so wie es in der Manpage beschrieben ist.

    Du hast außerdem nirgendwo *line_ptr und *t initialisiert - was zu undefiniertem Verhalten führen kann.

    Außerdem passen die Typen von t und dem Rückgabewert von malloc nicht zusammen.
    Zitat Zitat von DarKo87 Beitrag anzeigen
    Das ist ganz einfach ... damit eclipse aufhört zu meckern! Ohne Return, gibt der mir meistens Warnings aus. Daher hau ich einfach nen return 0; unten dran. Stören tuts eigentlich nicht, weil nen rückgabe wert gibts ja auch eigentlich nicht, schlicht nur speicher verschwendung.
    In C99 ist "return 0;" in dem Fall äquivalent zu "return NULL;". Das ist also schon OK.

    Gruß

    PS: Übrigens hatte ich schon mal einen Fehler in dem Buch "C von A bis Z" gemeldet, vom Verlag lediglich die Antwort
    bekommen: "Ja, wir sagen dem Autor Bescheid". Geändert hat sich (soweit ich weiß) aber nichts. Besorg dir lieber ein vernünftiges Buch.
     
    If at first you don't succeed, try again. Then quit. No use being a damn fool about it.

  12. #12
    DarKo87 DarKo87 ist offline Mitglied
    Registriert seit
    Nov 2007
    Beiträge
    15
    Zitat Zitat von deepthroat Beitrag anzeigen
    Besorg dir lieber ein vernünftiges Buch.
    Was kann man den als Nachschlagewerk nutzen?


    So sieht mein Code momentan aus, dank eurer hilfe hab ich ihn entsprechend angepasst.
    Nun stellt sich mir die frage, wie kann ich die Zeile die in line_ptr liegt in seine einzelteile zerlegen. Ich denke mit strcat ist schon sehr nachteilhaft, den das Programm würde dann sehr langsam laufen. Das würde ja jedes Zeichen an einen String anhängen, bis ein Abbruch Kriterium gefunden wäre, z.B. ein Sonderzeichen.

    Code :
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    
    /********************* function definitions *******************************/
    /***************************************************************************
    * @NAME: t_read
    * @FUNC: read all lines in open file*
    *
    ***************************************************************************/
     
    void *t_read (void){
     
        size_t len = 0;
     
        c_value(pthread_mutex_lock(&dataMutex));
     
        while((line_val=getline(&line_ptr, &len, datei)) != EOF){
            broadcast();
            pthread_cond_wait(&dataPresentCondition, &dataMutex);
        }
        pthread_mutex_unlock(&dataMutex);
     
        return 0;
    }
     
    Dieser Beitrag und sein Inhalt sind Geistiges Eigentum von DarKo87

    Mit freundlichen Grueßen / Best regards

    DarKo87

  13. #13
    deepthroat deepthroat ist offline Mitglied Diamant
    tutorials.de Premium-User
    Registriert seit
    Jun 2005
    Beiträge
    8.168
    Zitat Zitat von DarKo87 Beitrag anzeigen
    Was kann man den als Nachschlagewerk nutzen?
    Also als Nachschlagewerk eignet sich eigentlich am besten das Internet.

    Z.B. http://www.cplusplus.com/reference/ oder http://home.htw-berlin.de/~junghans/cref/index.html oder die Manpages z.B. hier http://linux.die.net/man/3/

    Oder einfach suchen. => Google, ixquick, usw.
    Zitat Zitat von DarKo87 Beitrag anzeigen
    So sieht mein Code momentan aus, dank eurer hilfe hab ich ihn entsprechend angepasst.
    getline gibt laut Manpage -1 bei einem Fehler zurück, EOF ist ein Integer Wert der nicht unbedingt -1 sein muss.
    Zitat Zitat von DarKo87 Beitrag anzeigen
    Nun stellt sich mir die frage, wie kann ich die Zeile die in line_ptr liegt in seine einzelteile zerlegen. Ich denke mit strcat ist schon sehr nachteilhaft, den das Programm würde dann sehr langsam laufen. Das würde ja jedes Zeichen an einen String anhängen, bis ein Abbruch Kriterium gefunden wäre, z.B. ein Sonderzeichen.
    Wie kommst du auf strcat wenn du etwas zerlegen möchtest?

    Siehe strpbrk bzw. strtok.

    Gruß
     
    If at first you don't succeed, try again. Then quit. No use being a damn fool about it.

Ähnliche Themen

  1. Antworten: 1
    Letzter Beitrag: 06.06.11, 19:19
  2. Antworten: 11
    Letzter Beitrag: 22.05.11, 21:11
  3. char wert anderem char zuweisen (char* )
    Von Dragon_Arch im Forum C/C++
    Antworten: 14
    Letzter Beitrag: 26.05.08, 20:52
  4. getline
    Von Beichtpfarrer im Forum C/C++
    Antworten: 7
    Letzter Beitrag: 15.09.05, 18:23
  5. CString -> char* Problem mit getline()
    Von tantor im Forum VisualStudio & MFC
    Antworten: 3
    Letzter Beitrag: 23.06.04, 08:20