473,398 Members | 2,404 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,398 software developers and data experts.

parameters or stdin

Greetings!

I need to write some C code that will decide between either reading from
stdin or take a file name from argv and process it.

The program needs to work like all of the typical unix utilities where
the file to process is either provided from a pipe/stream or argv.

Utilities like lp, tr, grep, etc.

So, when the command:

cat filename | grep -i > filename2

or

grep -i filename > filename2

executes, this acts like the programmtic interface i need.

I have tried everything I can think of from getc, getchar, read, gets,
etc. which all did not work. I test for EOF or NULL on the return values
and the program just hangs on a terminal read. So, the command:

cat filename | testprogram -dvalue

hangs on the reading from stdin and I never get to test for EOF.

What am i missing?

Do I need to set some type of fcntl flag and control the stdin flow
similar to a wait/nowait process?

BTW, i am compiling this on HP-UX B.11.00 Unix.

I need an answer ASAP!

Thanks in advance!
Nov 15 '05 #1
11 4308
David Warner wrote:
Greetings!

I need to write some C code that will decide between either reading from
stdin or take a file name from argv and process it.

The program needs to work like all of the typical unix utilities where
the file to process is either provided from a pipe/stream or argv.

Utilities like lp, tr, grep, etc.

So, when the command:

cat filename | grep -i > filename2

or

grep -i filename > filename2

executes, this acts like the programmtic interface i need.

I have tried everything I can think of from getc, getchar, read, gets,
etc. which all did not work. I test for EOF or NULL on the return values
and the program just hangs on a terminal read. So, the command:

cat filename | testprogram -dvalue

hangs on the reading from stdin and I never get to test for EOF.

What am i missing?


Probably you can show your code to see what's missing. This one works.

$ cat simplecat.c
#include <stdio.h>
#include <stdlib.h>

#define BUF_SIZE 100

int main(int argc, char ** argv)
{ char buf[BUF_SIZE + 1];
FILE * inp;

if(argc == 2)
{ inp = fopen(argv[1], "r");
if(!inp)
{ return EXIT_FAILURE;
}
}
else
{ inp = stdin;
}
while(fgets(buf, sizeof buf, inp))
{ printf("%s", buf);
}
fclose(inp);
return EXIT_SUCCESS;
}
ishs

Nov 15 '05 #2
In article <da****************************@corp.supernews.com >,
David Warner <da******@westbase.com> wrote:
I need to write some C code that will decide between either reading from
stdin or take a file name from argv and process it. I have tried everything I can think of from getc, getchar, read, gets,
etc. which all did not work. I test for EOF or NULL on the return values
and the program just hangs on a terminal read.


The usual thing to do it to see whether there's a filename argument
and read from stdin if there isn't. Trying to read is useless, since
there will always be either a file or a terminal on stdin (for typical
operating systems).

-- Richard
Nov 15 '05 #3
I did the exact same thing on HP-UX... this is how my code starts...

main(int argc, char *argv[])
{
if (argc > 1) {
if the arguments are greater than 1 (1 being the command) then process
them, else use a default. I wrote this to check the similarties
between 2 files. They are allways the same, but this way I can use it
to check whatever 2 files I wish. I can option to add file names or
use defaults.

Hope this helps,
-#2pencil-
http://www.akroncdnr.com

Nov 15 '05 #4

In article <d9***********@pc-news.cogsci.ed.ac.uk>, ri*****@cogsci.ed.ac.uk (Richard Tobin) writes:

The usual thing to do it to see whether there's a filename argument
and read from stdin if there isn't. Trying to read is useless, since
there will always be either a file or a terminal on stdin (for typical
operating systems).


Unix is atypical? A great many Unix processes are executed with
neither a file nor a terminal associated with stdin. Some have
nothing associated with stdin (for Unix implementations, this
means descriptor 0 does not refer to an open entry in the file
table); many more have other types of system objects associated
with stdin.

The language requires that (for a hosted implementation) at program
startup stdin be "predefined" and "need not be opened explicitly".
That doesn't mean that it must refer to something that can success-
fully be read. It's entirely possible that the first attempt to
read from stdin will result in EOF or an error.

None of that helps with the OP's question, of course.

--
Michael Wojcik mi************@microfocus.com

This book uses the modern technology to explain the phenomemon in the world
of Japanese animation. If you love anime so much, you'd better read this.
After you read it, you may agree that is destroying the dream of the child.
Needs Chinese viewing system. -- The Goodboy Scientific
Nov 15 '05 #5
In article <da*********@news4.newsguy.com>,
Michael Wojcik <mw*****@newsguy.com> wrote:
Trying to read is useless, since
there will always be either a file or a terminal on stdin (for typical
operating systems).
Unix is atypical? A great many Unix processes are executed with
neither a file nor a terminal associated with stdin.


I was referring to programs run from the command line, which was what
the OP seemed interested in.

-- Richard
Nov 15 '05 #6

In article <da**********@pc-news.cogsci.ed.ac.uk>, ri*****@cogsci.ed.ac.uk (Richard Tobin) writes:
In article <da*********@news4.newsguy.com>,
Michael Wojcik <mw*****@newsguy.com> wrote:
Trying to read is useless, since
there will always be either a file or a terminal on stdin (for typical
operating systems).

Unix is atypical? A great many Unix processes are executed with
neither a file nor a terminal associated with stdin.


I was referring to programs run from the command line, which was what
the OP seemed interested in.


Perhaps. We all write code that makes some assumptions. I merely
wanted to point out that this one - that stdin could be read
successfully - was not always justified.

It's not true of programs started from the Unix command line, either.
In ksh:

$ cat <&-
cat: cannot stat

Does anyone do that? Yes. (After all, the operator is there for a
reason.) I recently had to use this myself, to run a program (that
I couldn't modify) in the background with no controlling terminal
association.

Many Unix programs can assume that stdin is associated with a
readable entity at program startup, because their failure mode if
it is not is acceptable. Some cannot. I've dealt with programs
that had security holes if they opened a file and it received
descriptor 0, 1, or 2, because they assumed that stdin, stdout,
and stderr were valid at program startup.

--
Michael Wojcik mi************@microfocus.com

Thanks for your prompt reply and thanks for your invitatin to your
paradise. Based on Buddihism transmigration, I realize you, European,
might be a philanthropist in previous life! -- supplied by Stacy Vickers
Nov 15 '05 #7
In article <da********@news4.newsguy.com>,
Michael Wojcik <mw*****@newsguy.com> wrote:
Perhaps. We all write code that makes some assumptions. I merely
wanted to point out that this one - that stdin could be read
successfully - was not always justified.


The assumption relevant to this discussion is not that stdin can be
read. On the contrary, it's that the fact that stdin *can* be read
implies nothing about whether it's the intended input for the program.
I see no harm in ignoring the corner cases of unix when explaining how
to decide where to read input from.

To reiterate the possibly lost point: decide where to read from based
on the arguments, not on the state of stdin.

-- Richard
Nov 15 '05 #8
Richard Tobin wrote:
Michael Wojcik <mw*****@newsguy.com> wrote:
Perhaps. We all write code that makes some assumptions. I
merely wanted to point out that this one - that stdin could be
read successfully - was not always justified.


The assumption relevant to this discussion is not that stdin can
be read. On the contrary, it's that the fact that stdin *can* be
read implies nothing about whether it's the intended input for the
program. I see no harm in ignoring the corner cases of unix when
explaining how to decide where to read input from.

To reiterate the possibly lost point: decide where to read from
based on the arguments, not on the state of stdin.


On most systems it is possible to decide whether or not stdin is
connected to an interactive keyboard with slightly non-portable
code (which in turn can be replaced by something that reports
not-a-keyboard portably). This allows some easy up-front
decisions, such as whether to emit a help screen and exit. Very
useful for filters.

--
"If you want to post a followup via groups.google.com, don't use
the broken "Reply" link at the bottom of the article. Click on
"show options" at the top of the article, then click on the
"Reply" at the bottom of the article headers." - Keith Thompson
Nov 15 '05 #9
CBFalconer wrote:
Richard Tobin wrote:
Michael Wojcik <mw*****@newsguy.com> wrote:

Perhaps. We all write code that makes some assumptions. I
merely wanted to point out that this one - that stdin could be
read successfully - was not always justified.


The assumption relevant to this discussion is not that stdin can
be read. On the contrary, it's that the fact that stdin *can* be
read implies nothing about whether it's the intended input for the
program. I see no harm in ignoring the corner cases of unix when
explaining how to decide where to read input from.

To reiterate the possibly lost point: decide where to read from
based on the arguments, not on the state of stdin.

On most systems it is possible to decide whether or not stdin is
connected to an interactive keyboard with slightly non-portable
code (which in turn can be replaced by something that reports
not-a-keyboard portably). This allows some easy up-front
decisions, such as whether to emit a help screen and exit. Very
useful for filters.


Pray tell. Given foo, a program which takes no arguments and expects
input from stdin, I might invoke it two ways..

foo

in which case I am expected to enter data from the keyboard or..

foo < infile

in which case data comes to stdin from a file. How can I know from
within foo, which way foo was invoked?

--
Joe Wright
"Everything should be made as simple as possible, but not simpler."
--- Albert Einstein ---
Nov 15 '05 #10
On Sat, 02 Jul 2005 10:02:57 -0400, Joe Wright
<jo********@comcast.net> wrote:
CBFalconer wrote:

On most systems it is possible to decide whether or not stdin is
connected to an interactive keyboard with slightly non-portable
code (which in turn can be replaced by something that reports
not-a-keyboard portably). This allows some easy up-front
decisions, such as whether to emit a help screen and exit. Very
useful for filters.


Pray tell. Given foo, a program which takes no arguments and expects
input from stdin, I might invoke it two ways..

foo

in which case I am expected to enter data from the keyboard or..

foo < infile

in which case data comes to stdin from a file. How can I know from
within foo, which way foo was invoked?


You can't do it portably. The C standard has no concept of what (if
anything) might be attached to stdin (or stdout or stderr for that
matter) or any other file stream.

OFF TOPIC:

On some systems there is an operating system call like isatty(int fd)
which returns a true value if the file descriptor (not FILE pointer)
refers to an interactive device. For instance, on a POSIX system (like
most modern Unix-derived ones) see

http://www.opengroup.org/onlinepubs/...ns/isatty.html

You will need to pass it the value 0 (zero) for the file descriptor of
stdin, or you can get the file descriptor of any FILE pointer using
fileno()

http://www.opengroup.org/onlinepubs/...ns/fileno.html

Windows with the POSIX layer installed may also support those functions
in console mode, as may some other non-Unix systems, but you need to
read the manuals for your system. Hopefully the above will give a clue
where to look. So on a POSIX compliant system you could write:

if (!isatty(fileno(stdin)))
{
fprintf(stderr, "Input not interactive!\n");
exit(EXIT_FAILURE);
}

However, there is no guarantee that a human is on the other end, it
could be a serial port connected to another computer for instance.

As CBFalconer said, you can then wrap those in a function of your own in
a module which is known to be implementation specific, so that the rest
of your code will be portable (and on a system without any way of
determining what is connected to stdin can just always return false or
whatever).

Chris C
Nov 15 '05 #11
Joe Wright wrote:
CBFalconer wrote:

.... snip ...

On most systems it is possible to decide whether or not stdin is
connected to an interactive keyboard with slightly non-portable
code (which in turn can be replaced by something that reports
not-a-keyboard portably). This allows some easy up-front
decisions, such as whether to emit a help screen and exit. Very
useful for filters.


Pray tell. Given foo, a program which takes no arguments and
expects input from stdin, I might invoke it two ways..

foo

in which case I am expected to enter data from the keyboard or..

foo < infile

in which case data comes to stdin from a file. How can I know
from within foo, which way foo was invoked?


It is not properly portable, but I use the following, which is
arranged so that I do not have to inhibit proper checking in the
rest of the C file. If it doesn't work simply replace it by
something that does "return 0" and you are back where you are now.
The usage is simply:

if (akeyboard(stdin)) helpandexit();
else {
/* use the redirected stdin */
}

and it is all independent of whether or not foo takes arguments.

/* ------------------- */

/* This is very likely to be non-portable */
/* DOES NOT check fp open for reading */
/* NULL fp is considered a keyboard here! */
static int akeyboard(FILE *fp)
{
#ifndef __TURBOC__ /* Turbo C is peculiar */
# ifdef __STDC__
/* This dirty operation allows gcc -ansi -pedantic */
extern int fileno(FILE *fp);
extern int isatty(int fn);
# endif
#endif
return ((fp != NULL) && isatty(fileno(fp)));
} /* akeyboard */

--
"If you want to post a followup via groups.google.com, don't use
the broken "Reply" link at the bottom of the article. Click on
"show options" at the top of the article, then click on the
"Reply" at the bottom of the article headers." - Keith Thompson
Nov 15 '05 #12

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

3
by: lamar_air | last post by:
I have a fortran executable which when run from cmd it asks for a series of parameters which you enter then hit enter. From my python cgi script i want to be able to run the executable. Enter the...
46
by: J.R. | last post by:
Hi folks, The python can only support passing value in function call (right?), I'm wondering how to effectively pass a large parameter, such as a large list or dictionary? It could achieved...
1
by: lonelyplanet999 | last post by:
Hi, I'm a newbie of perl language and I would like to ask the differences in below pieces of code: 1. read(STDIN, $stuff, $ENV{'CONTENT_LENGTH'}); @pairs = split(/\&/, $stuff); 2.
4
by: Panos Laganakos | last post by:
Hello, I'd like to know how its possible to pass a data attribute as a method parameter. Something in the form of: class MyClass: def __init__(self): self.a = 10
5
by: Cameron Laird | last post by:
Question: import subprocess, StringIO input = StringIO.StringIO("abcdefgh\nabc\n") # I don't know of a compact, evocative, and # cross-platform way to exhibit this behavior. # For now, depend...
10
by: Matthew Wilson | last post by:
Lately, I've been writing functions like this: def f(a, b): assert a in assert b in The point is that I'm checking the type and the values of the parameters.
16
by: arne | last post by:
Hi all, imagine I call a function, but omit one of the parameters, like: foo.c: void foo( int a, int b ) { /* do something with a and b */ return; }
9
by: Peter Blues | last post by:
I'm trying to write from keyboard input to a txt file. I don't understand why the while loop below doesn't achieve this. I.. 1: open the file for writing through FILE pointer outstream 2: I get...
1
by: bharathv6 | last post by:
i need to do is modify the image in memory like resizing the image in memory etc ... with out saving it disk as i have to return back the image with out saving it disk PIL supports the use of...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.