Home > front end >  Passing file contents to a c executable doesn't seem to work
Passing file contents to a c executable doesn't seem to work

Time:10-07

I have this c executable called testFile file containing this code :

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(int argc, char *argv[]){
    printf("Number of arguments : %d\n Arguments : ", argc);
    for(int i = 0; i<argc-1;i  ){
        printf("%s\t", argv[i]);
    }
}

and along with it a file called test1 containing just the number 1 (echo 1 > test1)
When I call this line on the command line (zsh) :
./test < test1
the output I get is this :

Number of arguments : 1
Arguments : ./testFile

Shouldn't this show 2 arguments ? Along with the character 1 ? I want to find a way to make this 1 appear in the arguments list, is it possible ? Or is it just the way my shell handles arguments passed like that ? (I find it weird as cat < test1 prints 1)

CodePudding user response:

You're conflating standard input with command arguments.

main's argc and argv are used for passing command line arguments.

here, for example, the shell invokes echo with 1 command line argument (the 1 character), and with its standard output attached to a newly opened and truncated file test.

echo 1 > test1

here, the shell running test with 0 arguments and its standard input attached to a newly opened test1 file.

./test < test1

If you want to turn the contents of ./test1 into command line parameters for test, you can do it with xargs.

xargs test < test1

unrelated to your question:

    for(int i = 0; i<argc 1;i  ){

The condition for that should be i<argc. Like all arrays in C and just about every other language, the minimum valid index of argv is 0 and the maximum valid index is 1 less than its length. As commenters pointed out, argv[argc] is required to be NULL, so technically, argc is one less than the length of argv.

CodePudding user response:

If you want the contents of test1 to be available in argv, you can do:

./test $(cat test1)

Note that this is very different than:

./test "$(cat test1)"

which is also different from:

./test '$(cat test1)'.  # Does not do at all what you want!

The first option will present each "word" of the file as a distinct argument, while the second will present the contents of the file as a single argument. The single quotes version doesn't look inside the file at all, and is merely included here to give you something to experiment with.

  • Related