The way I've done this is to check for a file name on the command
line and open the file.  If there is no command line argument I
set the file pointer equal to stdin:

FILE *in;

if (argc == 1) {	/* Or other test for file name present */
   in = stdin;
else {
   in = fopen (argv[1], "r");	/* Or correct subscript as req'd */

**************** (UN)SIGNED CHARS ****************
The best option is not to write code which depends on the signed-ness of
chars.  The primary error is writing code which uses chars as tiny
integers.  In most cases, if you examine the resulting code, you will
find that this makes for no savings in code space, and often the code
is bigger and slower than if you just used ints (or possibly shorts)
instead.  If you have a large array of these things, there will be a
data savings by using chars.  To be safe, never use values outside
the range 0-127 with type char.

Neither K&R nor ANSI specify that chars must be signed.

K&R 1, section 6.1 in the Reference Manual, says:
	"Whether or not sign-extension occurs for characters is
	machine dependent ... Of the machines treated by this
	manual, only the PDP-11 sign-extends."
ANSI Standard, section, says of objects of type char:
	"... the behavior is implementation-defined: the values
	are treated as either signed or nonnegative integers."
The reason for this is that hardware varies as to whether
sign-extension is more expensive than zero-padding.  The idea was to
allow the compiler to generate the most efficient code when "plain"
char was specified.