I'm new to C programming, and I want to access the content of a text file pass as an argument.
When I execute my program:
./cat 10 60 < dog.txt
And when I run a for loop to iterate the arguments, it doesn't print the file that I'm passing as an argument.
./cat
10
60
So, I'm assuming that it is not considered as an argument. But, is there a way to pass a filename as an argument the way I did(./cat 10 60 < dog.txt
) and then access its content?
Thank you for the help,
CodePudding user response:
On a Unix system, every file has three standard file descriptors (numbers mapping to files)
0 - Stdin 1 - Stdout 2 - Stderr
When you use the redirect symbol (<), bash closes stdin, which normally reads from your keyboard, and remaps it to the file that you are redirecting from, dog.txt in this case.
You are correct that it is not passed in as an argument, but you can still get the data by using the read command to read from file 0
read(0, *buf, buf_size);
E: Barmar pointed out that you should use the stdio library to read from the input, which is more standard
CodePudding user response:
<
is a redirection operator provided by your shell.
This operator opens the file on its right-hand side for reading, and, by default, remaps the standard input (stdin
) of your program to be this file.
It is also possible to specify which file descriptor to remap with the form:
program [n]< file
wherein [n] is a number. The typical mapping between UNIX file descriptors and C Standard Library streams is
0
-stdin
1
-stdout
2
-stderr
but it is possible to open other file descriptors, and have your program read from them with man 2 read
.
Here's an example program. Note the differences between these two different sets of commands:
This
./a.out a b < file.txt
will print the strings a
and b
under the section listing the program arguments, and then it will print the contents of file.txt
.
Whereas this
./a.out a b file.txt
will print the strings a
, b
, and file.txt
under the section listing the program arguments, and then wait for you to type something in the terminal.
#include <stdio.h>
int main(int argc, char **argv) {
size_t line = 0;
char buffer[256];
puts("--- argv ---");
for (int i = 0; i < argc; i )
printf("arg #%d : %s\n", i, argv[i]);
puts("--- stdin ---");
while (fgets(buffer, sizeof buffer, stdin))
printf("%4zu|%s", line, buffer);
}