Auftrag zu vergeben: Output in Datei schreiben



  • Hallo liebe Leute,

    ich versuche seit Tagen den Output eines C Programms in eine Datei umzuleiten. Ich spreche einen Messverstärker per RS232-Schnittstelle (über USB-RS232 Konverter) über meinen Raspberry PI (Debian Wheezy) an und kriege es einfach nicht hin. Im Moment kriege ich mit meinem Programm genau das hin was ich brauche. Das Programm tut was es soll, jedoch erscheint der Output nur im Terminal. Kann mir jemand helfen und erklären, wie ich den Output in eine .txt oder .csv Datei speichern kann? Ich wäre sehr dankbar.

    #include <stdlib.h> 
    #include <string.h> 
    #include <stdio.h> 
    #include <unistd.h> 
    #include <fcntl.h> 
    #include <termios.h> 
    
    #define MODEM "/dev/ttyUSB0" 
    #define BAUDRATE B9600     
    
    int main(int argc,char** argv) 
    {    
        struct termios tio; 
        struct termios stdio; 
        struct termios old_stdio; 
        int tty_fd, flags; 
        unsigned char c='D'; 
        tcgetattr(STDOUT_FILENO,&old_stdio); 
        printf("Starte bitte %s /dev/ttyUSB0\n",argv[0]); 
        memset(&stdio,0,sizeof(stdio)); 
        stdio.c_iflag=0; 
        stdio.c_oflag=0; 
        stdio.c_cflag=0; 
        stdio.c_lflag=0; 
        stdio.c_cc[VMIN]=1; 
        stdio.c_cc[VTIME]=0; 
        tcsetattr(STDOUT_FILENO,TCSANOW,&stdio); 
        tcsetattr(STDOUT_FILENO,TCSAFLUSH,&stdio); 
        fcntl(STDIN_FILENO, F_SETFL, O_NONBLOCK);       // make the reads non-blocking 
        memset(&tio,0,sizeof(tio)); 
        tio.c_iflag=0; 
        tio.c_oflag=0; 
        tio.c_cflag=CS8|CREAD|CLOCAL;           // 8n1, see termios.h for more information 
        tio.c_lflag=0; 
        tio.c_cc[VMIN]=1; 
        tio.c_cc[VTIME]=5; 
        if((tty_fd = open(MODEM , O_RDWR | O_NONBLOCK)) == -1){ 
            printf("Error while opening\n"); // Just if you want user interface error control 
            return -1; 
        } 
        cfsetospeed(&tio,BAUDRATE);     
        cfsetispeed(&tio,BAUDRATE);            // baudrate is declarated above 
        tcsetattr(tty_fd,TCSANOW,&tio); 
        while (c!='q'){ 
            if (read(tty_fd,&c,1)>0){ 
                write(STDOUT_FILENO,&c,1); // if new data is available on the serial port, print it out 
                printf(""); 
            } 
            if (read(STDIN_FILENO,&c,1)>0){ 
                write(tty_fd,&c,1);//if new data is available on the console, send it to serial port 
                printf(""); 
            } 
        } 
        close(tty_fd); 
        tcsetattr(STDOUT_FILENO,TCSANOW,&old_stdio); 
        return EXIT_SUCCESS; 
    }
    

    Der Code soll so umgeschrieben werden, dass alle 60 Sekunden ein bestimmter Befehl gesendet wird und der Output dann fortlaufend in einer Datei gespeichert wird.
    Über eine Antwort wäre ich sehr dankbar, da mir die Zeit davonläuft.



  • Unter Windows würde man das Programm einfach mit

    Programm.exe parameter1 parameter2 parameter3 > OutputFile.txt
    

    aufrufen.
    (Bzw. mit ">>" statt ">" wenn der Output an ein bestehendes File angehängt werden soll.)
    Unter Linux (oder was auch immer auf nem Raspberry läuft) geht das sicher auch, vermutlich sogar mit der selben Syntax.

    Dabei wird dann einfach das was normalerweise in der Konsole (telnet/Terminal/...) landet in das File OutputFile.txt geschrieben.

    Wenn man trotzdem noch Output in der Konsole ausgeben will, kann man statt stdout stderr verwenden (stderr wird normalerweise nicht mit "umgelenkt", d.h. was nach stderr rausgeschrieben wird landet dann in der Konsole, der Rest im File).

    write(STDOUT_FILENO,"blub",4); // schreibt nach stdout
    write(STDERR_FILENO,"blub",4); // schreibt nach stderr
    printf("blub %d", 123); // schreibt nach stdout
    fprintf(stderr, "blub %d", 123); // schreibt nach stderr
    

    Ansonsten kannst du natürlich auch mit fopen() ein File aufmachen, und dann mit fprintf()/fwrite()/... reinschreiben.
    Und vor Programmende idealerweise wieder mit fclose() zumachen 😉



  • Der Code soll so umgeschrieben werden, dass alle 60 Sekunden ein bestimmter Befehl gesendet wird

    Brauchst du bei dem Teil auch Hilfe?

    Und muss das was der Messverstärker zurückliefert noch irgendwie "umformatiert" werden, oder kann das 1:1 so wie es ankommt in das Output-File geschrieben werden?


  • Mod

    hustbaer schrieb:

    Unter Linux (oder was auch immer auf nem Raspberry läuft) geht das sicher auch, vermutlich sogar mit der selben Syntax.

    Korrekt, man kann sogar noch viel lustigere Sachen machen, wie gezielt einzelne Ströme zu anderen Zielen leiten (zum Beispiel nur Fehlerausgaben in eine Datei), Ströme vervielfachen (Ausgabe auf Konsole und in Datei) oder Ströme an ungewöhnliche Ziele leiten (zum Beispiel andere Programme oder auf die Soundkarte) oder Kombinationen davon. Und die Hälfte der Möglichkeiten habe ich bestimmt vergessen. Kann Windows aber sicher auch 🙂 .

    Ansonsten kannst du natürlich auch mit fopen() ein File aufmachen, und dann mit fprintf()/fwrite()/... reinschreiben.
    Und vor Programmende idealerweise wieder mit fclose() zumachen 😉

    Oder, da hier ja anscheinend mit Linux gearbeitet wird, die Datei mit open öffnen, weiterhin write benutzen und dann close benutzen.

    Interessanter und wohl die eigentliche Hauptaufgabe für den, der das Projekt übernimmt, ist, dass das Programm selbst derzeit noch wesentlicher Korrekturen bedarf. IO macht man einfach nicht mit busy-waiting. Auch wenn's prinzipiell funktioniert, so dankt einem die CPU, wenn man stattdessen poll/select oder Ähnliches nutzt.
    So manches andere Konstrukt im Programm ist auch verbesserungswürdig.


Anmelden zum Antworten