2013-04-23 13 views
6

Wie kann ich die Linien trennen, die von einer Rohrleitung kommen. In dem Rohr ist dieser Text:Aus Rohr Linie für Linie in C lesen

HALLO:500\n 
TEST:300\N 
ADAD 
ADAWFFA 
AFAGAGAEG 

Ich möchte die Zeilen aus dem Rohr trennen, weil ich die Werte in Variablen speichern möchten.

Hier ist mein c-Code:

#include <stdio.h> 
#include <stdlib.h> 

#define BUFFERSIZE 1 

int main(int argc, char **argv){ 
    unsigned char  buffer[BUFFERSIZE]; 
    FILE       *instream; 
    int       bytes_read=0; 
    int       buffer_size=0; 


    buffer_size=sizeof(unsigned char)*BUFFERSIZE; 
    /* open stdin for reading */ 
    instream=fopen("/dev/stdin","r"); 

    /* did it open? */ 
    if(instream!=NULL){ 
     /* read from stdin until it's end */ 
     while((bytes_read=fread(&buffer, buffer_size, 1, instream))==buffer_size){ 
      fprintf(stdout, "%c", buffer[0]); 
     } 
    } 
    /* if any error occured, exit with an error message */ 
    else{ 
     fprintf(stderr, "ERROR opening stdin. aborting.\n"); 
     exit(1); 
    } 

    return(0); 
} 

Ist dies der richtige Weg aus der Leitung für die beste Zeile für Zeile zu lesen?

+0

'für das Beste' ist eine subjektive Frage. Stehen Sie wirklich vor einem Problem? – abasu

+0

Ersetzen Sie 'fread' durch [' fgets'] (http://pubs.opengroup.org/onlinepubs/009695399/functions/fgets.html). –

Antwort

13

Dies wird in der Regel nur von stdin Lesen genannt. Dem Programm sollte es egal sein, ob die Eingabe eine Pipe, eine umgeleitete Datei oder eine Tastatur ist.

fread wird nur gelesen, bis der Puffer voll ist. Verwenden Sie fgets, um eine Zeile zu lesen.

Auch die Puffergröße sollte groß genug sein, um die Linie zu halten. Für kleine einmalige Programme können Sie einfach eine Nummer wählen. Oder es gibt einen Standardnamen BUFSIZ, der Ihnen einen ziemlich großen Puffer gibt. Wie groß? Groß genug. "Ja wirklich?" Wahrscheinlich.

fgets die Newline-Zeichen in der Zeichenfolge kopieren, wenn die Zeichenfolge zuerst füllen. Sie können also das letzte Zeichen testen, um festzustellen, ob die Zeile abgeschnitten wurde oder nicht. Mit vernünftigen Eingaben wird das nicht passieren. Aber ein robusterer Ansatz würde einen größeren Puffer zuweisen, die partielle Zeile kopieren und fgets erneut aufrufen, um weiter zu versuchen, eine vollständige Zeile zu erhalten.

#include <stdio.h> 

int main() { 
    char buf[BUFSIZ]; 
    fgets(buf, sizeof buf, stdin); 
    if (buf[strlen(buf)-1] == '\n') { 
     // read full line 
    } else { 
     // line was truncated 
    } 
    return 0; 
} 

Diese bekommt man auf halben Weg zu dem gefürchteten Pufferüberlauf Problem geschützt. fgets schreibt nicht mehr als die übergebene Größe. Die andere Hälfte macht, wie oben erwähnt, etwas Sinnvolles mit den möglichen Teilzeilen, die sich aus unerwartet langen Eingabezeilen ergeben können.

+0

ok Hast du ein gutes Beispiel für die Verwendung von Fgets? – bladepit

+1

würde ich. Aber du solltest lernen, 'Mann fgets' für dich selbst zu machen. (Es ist das erste, was ich tun würde, um ein Beispiel zu schreiben. Ich bekomme immer die Argumente rückwärts, wenn ich schreibe, ohne zu überprüfen.) –

+1

Ich versuche nicht rotzig zu klingen. Ich denke wirklich, es ist das Beste für mich, kein solches Beispiel zu schreiben. –

1

Hier ist eine andere Option (ich bin mir nicht ganz sicher, ob es eine "richtige" Methode ist) - verwenden Sie die Anzahl der Bytes von der read Funktion gelesen. In diesem Beispiel habe ich von stdin gelesen, obwohl eine Umleitung gemacht wurde, so dass die fd in 0 ist eine Datei/Rohr/was auch immer Sie es brauchen.

while ((nbytes=read(STDIN_FILENO, buffer, MAX_PIPE_SIZE)) > 0) { 
    write(STDOUT_FILENO, buffer, nbytes); 
    }