reading and monitoring file content!

J

JSonic

Good Morning mates.
Hope I can solve a little issue here.

Im stuck trying to build a script. I want it to open a file, read it,
them at the end, my script keep monitoring that file. Its a binary
file /dev/dsp. That file is receiving data from one mic plugged in my
lap.

So far so good. The only thing is when my script gets the EOF it
closes and I want it to still monitoring the file.

Is there any way to do it?
That¶ my script:

#include<stdio.h>

main () {
FILE *p;
char str[20], c;

printf("Arquivo: ");
gets(str);

p = fopen(str, "rb");

while(!feof(p)) {
fscanf(p, "%c", &c);
printf("%c", c);
}
fclose(p);
return 0;
}



P.s. All the data is been added at the end of the file, there's no
modification in the file content, so shouldn't be difficult.

Tks a lot!
 
M

Mark Wooding

JSonic said:
Good Morning mates.
Hope I can solve a little issue here.

Im stuck trying to build a script. I want it to open a file, read it,
them at the end, my script keep monitoring that file. Its a binary
file /dev/dsp. That file is receiving data from one mic plugged in my
lap.

So far so good. The only thing is when my script gets the EOF it
closes and I want it to still monitoring the file.

On Linux, at least, /dev/dsp never reaches end-of-file.
Is there any way to do it?

fseek(fp, 0, SEEK_CUR) and try again?
ThatÅ› my script:

#include<stdio.h>

main () {
FILE *p;
char str[20], c;

printf("Arquivo: ");
gets(str);

gets is evil and shouldn't be used. For this, you're better off using a
command-line argument. 20 bytes is too short for a filename on many
systems.
p = fopen(str, "rb");

You don't check whether this gave you a null pointer.
while(!feof(p)) {
fscanf(p, "%c", &c);
printf("%c", c);
}

This is wrong.

(a) You should continue until a read operation reports EOF. Only
after that has happened will feof return nonzero. So this code
will actually write the last character of the input twice.

(b) fscanf and printf are very slow ways of doing this. Maybe
getc/putc are what you want; maybe fread/fwrite. Maybe you should
just call cat. Or, if you want it to ignore EOF and keep trying
anyway, tail -c+1 -f.
fclose(p);
return 0;
}

-- [mdw]
 
Q

qarnos

Good Morning mates.
Hope I can solve a little issue here.

I'll try an answer as best I can, but this will surely be inadequate!
Im stuck trying to build a script.

<nitpick>
Programs written in languages which are typically compiled, such as C,
are usually referred to as "programs", not "scripts". The word
"script" is usually applied to interpreted languages such as Perl.
Note that there is nothing to stop someone from creating a C
interpreter or a Perl compiler - but it still seems weird to me when
someone talks about a "C script"!
I want it to open a file, read it,
them at the end, my script keep monitoring that file. Its a binary
file /dev/dsp. That file is receiving data from one mic plugged in my
lap.

I'm not sure if there is a way to do this in standard C. You might
want to try googling "file sharing" or something similar.

You will probably need to enquire on a newsgroup which is specific to
the platform you are targeting. For example, my memory on the MS-
Windows API is hazy, but there is a FindFirstChangeNotification
function which would help you, if you were using MS-Windows.
So far so good. The only thing is when my script gets the EOF it
closes and I want it to still monitoring the file.

Is there any way to do it?

I suspect probably not. There are many people on this group who are
more informed than myself, so they may be able to help you more.

The C89/90 standard, which is the only one you can currently rely on
being widely supported, is pretty old. A lot of this file shared stuff
simply wasn't an issue 20 years ago, so you don't find much standard
support for it.
That¶ my script:

#include<stdio.h>

main () {

Oops! You forgot to specify the return value of main(), which is 'int'
in "hosted implementations" (a technical term for most C compilers).

IIRC, this is strictly OK in C89/90, since it assumes an 'int' return,
but it is an error in C99. You'd be best to write:

int main() {
... yada yada yada ...
}

Others prefer:

int main(void) {
... yada yada yada ...
}

Note the 'void' function parameter. I, personally, don't think it's
necessary, but arguments have been made on this group that a strict
interpretation of C99 requires it.

I still don't do it, though.
        FILE *p;
        char str[20], c;

        printf("Arquivo: ");
        gets(str);

gets() is generally a bad way to go, especially with a buffer size so
small. Try entering a 25 character filename and see what happens. You
might come out of it with no adverse affects. You also might launch a
nuclear missile strike against North Korea. Such is the wonder of
Undefined Behaviour.

Look-up fgets(). If you use code like fgets(str, 20, stdin), your code
will be much safer. Sure, this is a trivial program, but old habits
die hard! Plus, you can sleep easy without worrying about nuclear
strikes.

While you're at it, it would be better to replace the '20' with a
macro or enum, such as this:

#define BUFFER_SIZE 20

.... OR ...

enum { BUFFER_SIZE = 20 };



int main() {
char str[BUFFER_SIZE]

fgets(str, BUFFER_SIZE, stdin);

... yada yada yada ...
}

HTH.
 
F

Flash Gordon

Mark said:
On Linux, at least, /dev/dsp never reaches end-of-file.


fseek(fp, 0, SEEK_CUR) and try again?

From a C perspective fun, but not necessarily the way to go...
ThatÅ› my script:

#include<stdio.h>

main () {
FILE *p;
char str[20], c;

printf("Arquivo: ");
gets(str);

gets is evil and shouldn't be used. For this, you're better off using a
command-line argument. 20 bytes is too short for a filename on many
systems.

Very true.
You don't check whether this gave you a null pointer.


This is wrong.

An even bigger reason, is that having solved the problem of EOF, it
could then end up in a "busy loop" monitoring for more data to appear in
/dev/dsp.
(a) You should continue until a read operation reports EOF. Only
after that has happened will feof return nonzero. So this code
will actually write the last character of the input twice.

(b) fscanf and printf are very slow ways of doing this. Maybe
getc/putc are what you want; maybe fread/fwrite. Maybe you should
just call cat. Or, if you want it to ignore EOF and keep trying
anyway, tail -c+1 -f.

Or use system specific calls to wait for data to arrive in /dev/dsp and
read it only when you know there is data to read.
 
M

Mark Wooding

qarnos said:
<nitpick>
Programs written in languages which are typically compiled, such as C,
are usually referred to as "programs", not "scripts". The word
"script" is usually applied to interpreted languages such as Perl.
Note that there is nothing to stop someone from creating a C
interpreter or a Perl compiler - but it still seems weird to me when
someone talks about a "C script"!
</nitpick>

#! /usr/bin/tcc -run
#include <stdio.h>
int main(void) { puts("Hello, world!"); return (0); }

-- [mdw]
 
M

Mark Wooding

Flash Gordon said:
An even bigger reason, is that having solved the problem of EOF, it could
then end up in a "busy loop" monitoring for more data to appear in
/dev/dsp.

If /dev/dsp reports EOF, there's no significantly better way of waiting
until it `unreports' EOF -- which is why tail(1) goes into a sleep(3)
loop. Some more modern tails use inotify, but I don't think that'd do
any good on a character special.

Of course, all of this is counterfactual musing anyway, since /dev/dsp
doesn't report EOF.
Or use system specific calls to wait for data to arrive in /dev/dsp and read
it only when you know there is data to read.

It'll block anyway unless you did something weird.

-- [mdw]
 
L

luserXtrog

Good Morning mates.
Hope I can solve a little issue here.

Im stuck trying to build a script. I want it to open a file, read it,
them at the end, my script keep monitoring that file. Its a binary
file /dev/dsp. That file is receiving data from one mic plugged in my
lap.

So far so good. The only thing is when my script gets the EOF it
closes and I want it to still monitoring the file.

Is there any way to do it?
That¶ my script:

#include<stdio.h>

main () {
        FILE *p;
        char str[20], c;

        printf("Arquivo: ");
        gets(str);

        p = fopen(str, "rb");

        while(!feof(p)) {
                fscanf(p, "%c", &c);
                printf("%c", c);
        }
       fclose(p);
       return 0;

}

P.s. All the data is been added at the end of the file, there's no
modification in the file content, so shouldn't be difficult.

Tks a lot!

You might have better luck with POSIX non-blocking IO. Try searching
the archives of comp.unix.programmer for fcntl, select, and
O_NONBLOCK.

Flipping to my post-it note in Practical Unix Programming, I find the
following:

Example 3.22
The following code segment sets an already opened file descriptor fd
for non-blocking I/O.

#include <fcntl.h>
#include <stdio.h>
int fd_flags;

if ((fd_flags = fcntl(fd, F_GETFL, 0)) == -1)
perror("Could not get flags for fd");
else {
fd_flags |= O_NONBlOCK;
if (fcntl(fd, F_SETFL, fd_flags) == -1)
perror("Could not set flags for fd");
}

More from text:
After this segment executes, read system calls associated with fd
return immediately if there is no input available.
Next to which I find scribbled:
returning -1, setting errno to EAGAIN

This may get you started, but it looks like you need to tap in to the
file at a lower level than C per se can handle.

hth
 
B

Ben Bacarisse

You might have better luck with POSIX non-blocking IO. Try searching
the archives of comp.unix.programmer for fcntl, select, and
O_NONBLOCK.

This is an example of why comp.unix.programmer would be a better place
to ask. I doubt that there is any value in using non-blocking IO but,
of course, I could be wrong and you could be right. A long thread to
thrash out the pros and cons of this would be way to resolve the
matter but here is the wrong place for it!
 
L

luserXtrog

This is an example of why comp.unix.programmer would be a better place
to ask.  I doubt that there is any value in using non-blocking IO but,
of course, I could be wrong and you could be right.  A long thread to
thrash out the pros and cons of this would be way to resolve the
matter but here is the wrong place for it!

True. Yet my sense of democracy favors more discussion rather
than less. To me, non-blocking i/o seems ideally suited to the
issue of whether or not there's anything to read. And if you're
only dealing with one file, you can keep it single threaded and
not have to worry about select.

I hadn't seen any similar advice in this thread, so I offered
something, in addition to a referral. I agree that
comp.unix.programmer is more appropriate. But the question had
not be un-asked.
 
J

JSonic

Tks mates.

For the moment Im ok 'cause my file never reaches the EOF.
But I was wondering if in case it does reach the EOF what would be the
best solution for.

Anyways, Ill try it later and be sure Im gonna post just for
reference!

C ya.
 

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

No members online now.

Forum statistics

Threads
473,770
Messages
2,569,583
Members
45,074
Latest member
StanleyFra

Latest Threads

Top