Newbie: Output to a file

S

Stefan Nowy

Hello!

I'm getting data from the serial port which is printed on the screen:
do
{
res = read(fd,buf,48);
buf[res]=0;
fprintf(stdout,"%s\n",buf);
}
while (TRUE);

So far so good. Data is received and printed out.
But as soon as I try to write that data in a file it doesn't work.
I tried openening a file and using fprintf(fp,"%s\n",buf); :
my program seems not to execute the above code, although the output-file
was opened correctly...
and on the commandline "./myprog > ouput.txt" creates the output.txt,
but no data occurs...

Can anybody help me?

Thanks and Greetings

Stefan
 
J

Joona I Palaste

Stefan Nowy said:
I'm getting data from the serial port which is printed on the screen:
do
{
res = read(fd,buf,48);
buf[res]=0;
fprintf(stdout,"%s\n",buf);
}
while (TRUE);
So far so good. Data is received and printed out.
But as soon as I try to write that data in a file it doesn't work.
I tried openening a file and using fprintf(fp,"%s\n",buf); :
my program seems not to execute the above code, although the output-file
was opened correctly...
and on the commandline "./myprog > ouput.txt" creates the output.txt,
but no data occurs...

Please show the code you're using to open the file and print to it.
We're not mind-readers.
 
S

Stefan Nowy

Joona said:
Please show the code you're using to open the file and print to it.

Okay, here's all of my code. I am aware that the file is never closed;
but I tested it without the serial port part, and it did work... but I
am open for suggestions. ;-)

Stefan


#include <stdio.h>
#include <string.h>

#define IN "/dev/XPort"
#define OUTPUT "/home/sn/wechs.txt"
#define FALSE 0
#define TRUE 1

int main()
{
int i,res;
int fd;
char buf[255];
FILE *fp_out;


fd = open(IN, "r" );
if (fd <0) { exit(-1); }

if ((fp_out = fopen(OUTPUT, "w")) == NULL)
{
printf("Ooops...\n");
exit(-1);
}


/* Get data all over again */

while (TRUE)
{

/* Wait for beginning of line */

do
{
read(fd,buf,1);
}
while (buf[0]!='#');


/* Line started; begin extracting the data */

{
res = read(fd,buf,21); /* Discard */
res = read(fd,buf,4);
buf[res]=0;
// fprintf(stdout,"%s\n",buf);
fprintf(fp_out,"%s\n",buf);
}


}

fclose(fp_out);
close(fd);

return 0;
}
 
N

Nick Austin

#include <stdio.h>
#include <string.h>

#define IN "/dev/XPort"
#define OUTPUT "/home/sn/wechs.txt"
#define FALSE 0
#define TRUE 1

int main()
{
int i,res;
int fd;
char buf[255];
FILE *fp_out;


fd = open(IN, "r" );
if (fd <0) { exit(-1); }

if ((fp_out = fopen(OUTPUT, "w")) == NULL)
{
printf("Ooops...\n");
exit(-1);
}


/* Get data all over again */

while (TRUE)
{

/* Wait for beginning of line */

do
{
read(fd,buf,1);
}
while (buf[0]!='#');


/* Line started; begin extracting the data */

{
res = read(fd,buf,21); /* Discard */
res = read(fd,buf,4);
buf[res]=0;
// fprintf(stdout,"%s\n",buf);
fprintf(fp_out,"%s\n",buf);
}


}

fclose(fp_out);
close(fd);

return 0;
}

Either you have set you compiler to give too few warnings or
you are ignoring the ones it gives. I get:

test.c(17) Warning: implicit declaration of function 'open'
test.c(47) Warning: implicit declaration of function 'read'
test.c(55) Warning: implicit declaration of function 'close'

You need to include the header file that defines these functions.

Also many of the functions you call set a return code.
Testing the return code will tell you which function is failing.

Nick.
 
B

Barry Schwarz

Okay, here's all of my code. I am aware that the file is never closed;
but I tested it without the serial port part, and it did work... but I
am open for suggestions. ;-)

snip reasonable looking code with some non-standard function calls.
if ((fp_out = fopen(OUTPUT, "w")) == NULL)
{
printf("Ooops...\n");
exit(-1);
}


/* Get data all over again */

while (TRUE)
{

snip some more
while (buf[0]!='#');


/* Line started; begin extracting the data */

{
res = read(fd,buf,21); /* Discard */
res = read(fd,buf,4);
buf[res]=0;
// fprintf(stdout,"%s\n",buf);
fprintf(fp_out,"%s\n",buf);
snip

fclose(fp_out);
close(fd);

return 0;
}


Uncomment the fprintf. Tell us what you see on the screen AND tell us
what tool you are looking at to view the file. Is there any chance
the input contains values that can be interpreted as '\0', '\n', etc?


<<Remove the del for email>>
 
S

Stefan Nowy

Nick said:
Either you have set you compiler to give too few warnings or
you are ignoring the ones it gives. I get:

I got no warnings using "gcc -o xport xport.c" to compile it...

Stefan
 
S

Stefan Nowy

Barry said:
/* Line started; begin extracting the data */

{
res = read(fd,buf,21); /* Discard */
res = read(fd,buf,4);
buf[res]=0;
// fprintf(stdout,"%s\n",buf);
Uncomment the fprintf. Tell us what you see on the screen AND tell us
what tool you are looking at to view the file.

Okay. just tried that. the program crashes. either way. I investigated
it some more, please see below.
Is there any chance
the input contains values that can be interpreted as '\0', '\n', etc?

I just get some numbers (like 0120); the outputfile has 0 bytes
("./xport > ouput.txt", if The data is printed to stdout)

Okay. Heres a part of my code again:

fd = open(IN, "r" );
if (fd <0) { exit(1); }

if ((fp_out = fopen(OUTPUT, "w")) == NULL)
{
printf("Ooops...\n");
exit(2);
}

after compiling and running it, the program exits with 1, so it failed
opening the source (serial port).
If the second part (the output file opening) is commented out, the
program works just fine (output to the screen)...

Any ideas?

Stefan
 
D

Dan Pop

In said:
I got no warnings using "gcc -o xport xport.c" to compile it...

Add -Wall and fix your code until the compiler silently accepts it.
When it complains about undeclared functions, don't provide dummy
declarations yourself, include the right headers instead.

Furthermore, don't use *any* library function without carefully reading
its specification first and without checking if its call succeeded or not.

Dan
 
D

Dave Thompson

Hello!

I'm getting data from the serial port which is printed on the screen:
do
{
res = read(fd,buf,48);
buf[res]=0;
fprintf(stdout,"%s\n",buf);
}
while (TRUE);

So far so good. Data is received and printed out.
But as soon as I try to write that data in a file it doesn't work.
I tried openening a file and using fprintf(fp,"%s\n",buf); :
my program seems not to execute the above code, although the output-file
was opened correctly...
and on the commandline "./myprog > ouput.txt" creates the output.txt,
but no data occurs...
Note that you don't want to do _both_ the things you describe.

Although it's outside the scope of C as such, on many systems
./myprog > output.txt
will (re)direct to the specified file any output by the program _on
stdout_ -- that is by printf, putchar, etc., or by fprintf, fputc,
etc. using (the value of) stdout for the fp argument.

On any (hosted) C implementation, output using fprintf, fputc, etc.
using an fp returned from a successful fopen with some filename and a
mode of (or including) "w", will go to that file. (Barring bugs of
course, or as Dan P complains special semantics like /dev/zero.)

If your program explicitly fopen's some (ordinary) file say "foo.txt"
and you also redirect to (or from) that file like "prog >foo.txt", you
are actually doing or attempting _two different_ opens of the same
file, and depending on your OS and perhaps your C runtime you may get
an error, or incorrect output: only that written by one path, or the
other, or some mixture, or some part or part(s) of either or both.

- David.Thompson1 at worldnet.att.net
 
C

Charlie Gordon

Hello,
See comments embedded in code.
#include <stdio.h>
#include <string.h>

missing non standard header files such as said:
#define IN "/dev/XPort"
#define OUTPUT "/home/sn/wechs.txt"
#define FALSE 0
#define TRUE 1

int main()
{
int i,res;
int fd;
char buf[255];
FILE *fp_out;


fd = open(IN, "r" );

Should be fd = open(IN, O_RDONLY);
Or you could use fopen() and getc() with better luck.
given the proper flags (-Wall -O) gcc would have complained that you call open()
without proper declaration first
and had you included unistd.h, gcc would have complained about the argument type
mismatch.
Instead, it passes a pointer as the second argument, and open interprets that
value as a combination of bits.
Open may fail or succeed in unpredictable ways, such opening the file for output
only.
if (fd <0) { exit(-1); }

You should output a more understandable diagnostics message, such as :
fprintf(stderr, "cannot open %s : %s\n", IN, strerror(errno));
or
perror(IN);
if ((fp_out = fopen(OUTPUT, "w")) == NULL)
{
printf("Ooops...\n");

See above remark;
exit(-1);
}


/* Get data all over again */

while (TRUE)

use for (;;) instead, but realize that this program never stops.
{

/* Wait for beginning of line */

do
{
read(fd,buf,1);
}
while (buf[0]!='#');

This may cause an infinite loop, you don't test for end of file or any error
condition.
Instead use:

for (;;) {
ssize_t n = read(fd, buf, 1);
if (n < 0) {
// deal with I/O error
} else
if (n == 0) {
// deal with early end of file
} else {
if (buf[0] == '#')
break;
}
}

Using standard I/O functions would make this more more straightforward and
efficient as well.
/* Line started; begin extracting the data */
res = read(fd,buf,21); /* Discard */

You should test that 21 bytes have actually been read
res = read(fd,buf,4);

You should even more importantly test that these 4 bytes have been read.
buf[res]=0;

In case of I/O error, this line will invoke undefined behaviour, possibly a
program crash
// fprintf(stdout,"%s\n",buf);
fprintf(fp_out,"%s\n",buf);

fprintf() will stop at the first '\0' encountered in buf. In the input contains
such a character, the characters after that will be lost.
Not to mention text mode vs: binary mode issues.

There is no provision for this loop to end. gcc -Wall -O would alert you of
this probable oversight.
fclose(fp_out);
close(fd);

return 0;
}

Now you can fix the program !

Chqrlie.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
474,151
Messages
2,570,854
Members
47,394
Latest member
Olekdev

Latest Threads

Top