So I\'m trying to get the C program to read a filename from the command line in the following format: cat (filename path) | (program name)
i can get it to read the n
The reason your program can't get the file name is because you're not giving it to it.
If you run your program as:
prog hello.txt
it's given the argument hello.txt
in argc/argv
.
However, what you're doing is:
cat hello.txt | prog
which means the shell is opening the file and feeding it into the standard input of your program. Actually, to be more accurate, cat
is opening the file and the shell is simply connecting the standard output of cat
to the standard input of prog
.
One way around this is to check the number of arguments (argc
is usually the count, argv[]
the values, despite the roundabout way you have it in your code) and, if it's zero, argc == 1
, read your file from standard input.
Only if an argument is given do you open that file and read it. That's the way a lot of UNIX utilities work:
od -xcb hello.txt # will dump the file.
cat hello.txt | od -xcb # will dump the file, but using standard input.
echo hello | od -xcb # will dump your "hello" string.
Some even change their behaviour depending on how they're invoked, wc
being one example - it shows the file name(s) if it knows them:
pax> wc -l qq.c
29 qq.c
pax> cat qq.c | wc -l
29
pax> wc -l *.c
0 a b.c
168 binmath.c
49 qq-save.c
29 qq.c
11 qq2.c
5 qqq.c
18 xx.c
280 total
pax> cat *.c | wc -l
280
Note that last case - because all files are being presented over the single standard input stream, there's no way to tell how many files there are. wc
will just tally up the entire contents of that stream.
Try this instead:
#include <stdio.h>
#include <string.h>
#define DEFAULT_LEN 70
int main (int argc, char *argv[]) {
FILE *file;
// Either select standard input or open the given file.
if (argc == 1) {
file = stdin;
} else {
file = fopen (argv[1], "r");
if (file == NULL) {
printf ("I'm sorry Dave, I can't do that\n");
printf (" (open the file '%s', that is).\n", argv[1]);
return 1;
}
}
// Now you're connected to stdin or the file itself, no
// difference in handling them (unless you do weird fseek
// sort of stuff).
char temp[DEFAULT_LEN];
fgets (temp, DEFAULT_LEN, file);
printf ("%s\n", temp);
// Only close file if you opened it yourself.
if (argc != 1)
fclose (file);
return 0;
}
This allows you to use both the file and standard input method as follows:
pax> prog prog.c
#include <stdio.h>
pax> echo hello | prog
hello
To read from the contantenated, you need to read from STDIN
char c = (char)fgetc(stdin)
Piping content into a process does not put the values into argv
; rather, it puts the values onto that process's stdin
.
You need to check if argc
is greater than 1. If it is, then argv[1]
has the filename you've been given (well, the first argument to the program, anyway). If not, you need to read from stdin
to get the filename.