简体   繁体   中英

Passing file contents to a c executable doesn't seem to work

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 )

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 .

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.

argv[0] is always the name of the executable itself. With your way of invoking the command, you did not pass any command at all. You would have to invoke it from zsh as ./testFile test1 if you want your program to see the name of the data file, or ./testFile $(<test1) if you want it to see the content of the data file.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM