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 mitfprintf()/fwrite()/...
reinschreiben.
Und vor Programmende idealerweise wieder mitfclose()
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?
-
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 mitfprintf()/fwrite()/...
reinschreiben.
Und vor Programmende idealerweise wieder mitfclose()
zumachenOder, 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.