reading input from a system call

J

jan olieslagers

I need to read the last line of a text file, then process its data in my
C code. Something like

tail DATAFILE | scanf ....

unfortunately the first command is shell, the second is C
I know I can perform a "system" command in my C code,
but how do I feed its yield to scanf or whatever?

Thanks in advance,
 
J

Joachim Schmitz

jan said:
I need to read the last line of a text file, then process its data in
my C code. Something like

tail DATAFILE | scanf ....

unfortunately the first command is shell, the second is C
I know I can perform a "system" command in my C code,
but how do I feed its yield to scanf or whatever?

a) be simply reading from stdin in your C-program
b) see whether you implementation provides pipe()

Bye, Jojo
 
K

Kenny McCormack

I need to read the last line of a text file, then process its data in my
C code. Something like

tail DATAFILE | scanf ....

unfortunately the first command is shell, the second is C
I know I can perform a "system" command in my C code,
but how do I feed its yield to scanf or whatever?

popen()

Now, expect a chorus of the usual:

Off topic. Not portable. Cant discuss it here. Blah, blah, blah.

from the usual crowd of "regulars".

--
Useful clc-related links:

http://en.wikipedia.org/wiki/Aspergers
http://en.wikipedia.org/wiki/Clique
http://en.wikipedia.org/wiki/C_programming_language
 
J

Joachim Schmitz

Joachim said:
a) be simply reading from stdin in your C-program
b) see whether you implementation provides pipe()

Nonsens, I meant popen()

Bye, Jojo
 
V

vippstar

I need to read the last line of a text file, then process its data in my
C code. Something like

tail DATAFILE | scanf ....

unfortunately the first command is shell, the second is C
I know I can perform a "system" command in my C code,
but how do I feed its yield to scanf or whatever?

Thanks in advance,


You don't need to use the shell. This can be done entirely in standard
C.

Write a function to read a line from the stream. Assuming getline
returns a malloc'ed read line from the stream:

char *p, lastline = NULL;
while((p = getline(stream)) != NULL) {
free(lastline);
lastline = p;
}
/* operate on lastline */
free(lastline);
 
J

jan olieslagers

(e-mail address removed) schreef:
You don't need to use the shell. This can be done entirely in standard
C.

Write a function to read a line from the stream. Assuming getline
returns a malloc'ed read line from the stream:

char *p, lastline = NULL;
while((p = getline(stream)) != NULL) {
free(lastline);
lastline = p;
}
/* operate on lastline */
free(lastline);

I was going to say this will read my whole datafile on every execution
(it is a once per second loop) but then I realised that the "tail"
command is very likely to do exactly the same thing...
So even this seems like a good approach, I'm afraid it's a bit over my
head (I consider myself an early beginner in C) si will first see what
popen can do for me - it's a command I hadn't even heard of.

Thanks to all who responded, I've got enough inspiration to plod on!
KA
 
K

Keith Thompson

jan olieslagers said:
(e-mail address removed) schreef:

I was going to say this will read my whole datafile on every execution
(it is a once per second loop) but then I realised that the "tail"
command is very likely to do exactly the same thing...
So even this seems like a good approach, I'm afraid it's a bit over my
head (I consider myself an early beginner in C) si will first see what
popen can do for me - it's a command I hadn't even heard of.

(The "tail" command, with no additional options, prints the last 10
lines of its input.)

Actually, it's fairly likely that the "tail" command *won't* read the
entire data file. It's likely to use implementation-specific tricks.
For that matter, you can *almost* do the same thing without using any
implementation-specific tricks: use fseek() to jump to a point not far
from the end of the file, then read from there. If some of the last
10 lines are particularly long, try again from an earlier point. The
only problem is that the standard doesn't guarantee that you can do
this; the offset argument to fseek must be either 0 or a value
returned by a previous call to ftell. If absolute 100% portability
isn't an issue, you can do the same thing yourself -- or you can let
the "tail" command do that work for you.

Since both the "tail" command and the "popen" function are defined by
POSIX, not by the C standard, comp.unix.programmer would be a better
place to ask about them.
 
B

Ben Bacarisse

You don't need to use the shell. This can be done entirely in standard
C.

Write a function to read a line from the stream. Assuming getline
returns a malloc'ed read line from the stream:

You don't need to store the lines. C permits an fseek to a previously
recorded position, so you can simply read a character at a time and
store the result of ftell every time you see a '\n'. You can even
count the length of the line (since you need to read to the end
anyway) so no dynamic reallocation is required (it is not hard but it
bother beginners). Also, if the code is to print the last line, then
this method requires no allocation at all.

I am tempted to leave the details as an exercise, but rather than post
code, but I can do that if anyone prefers.
 
J

jan olieslagers

Malcolm McLean schreef:
The non-standard way is popen(), which is probably the way to go.
However if you are a stdlib only type person,

system("tail DATAFILE > temp.txt");
fp = fopen(temp.txt", "r");

You can be more sophisticated by calling tmpnam() to generate a
temporary name.

Thank you sir, I don't think I qualify as an <anything>-only person...
The tmpnam function is one more I had never heard of, will look into
that one day when I find time, not the first couple of years likely...
Sincere gratitude!
KA
 
B

Ben Bacarisse

jan olieslagers said:
Malcolm McLean schreef:

Thank you sir, I don't think I qualify as an <anything>-only person...
The tmpnam function is one more I had never heard of, will look into
that one day when I find time, not the first couple of years
likely...

Please don't use system or popen for this relatively simple task
unless the program is short throw-away (in which case there are better
choices than C).

See my other post for a method and ask for my code if this is not in
fact a piece of coursework (and you don't want the joy of coding it!).
 
S

S M Ryan

jan olieslagers said:
I need to read the last line of a text file, then process its data in my
C code. Something like

tail DATAFILE | scanf ....

unfortunately the first command is shell, the second is C
I know I can perform a "system" command in my C code,
but how do I feed its yield to scanf or whatever?

If you're interested in a Unix-specific solution, you can use popen().
 

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,780
Messages
2,569,611
Members
45,280
Latest member
BGBBrock56

Latest Threads

Top