Yousef Ali
Yousef Ali

Reputation: 45

can't read argv[2] from main function in C

I am trying to run java jar using system() function from stdlib.h but I can't print argv[2] this is the code

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

int main(int argc, char* argv[])
{
    char command[] = "java -jar lans.jar ";
    char space[] = " ";

    if (argc == 2)
    {
        char* option = argv[1];
        strcat(command, option);
        printf(command);
        system(command);
    }
    else if (argc == 4)
    {
        char* option = argv[1];
        strcat(option, space);

        char* ip = argv[2];
        strcat(ip, space);

        char* file = argv[3];
        strcat(file, space);

        strcat(command, option);
        strcat(command, ip);
        strcat(command, file);
        printf(command);
        system(command);
    }
    else
    {
        printf("wrong args\n");
        system(command);
    }
}

This is the output

PS C:\Users\Josep\Dev\C> .\bin\lans.exe arg1 arg2 arg3
        option                            use
        ------------------------------------------
        -s [target ip] [file name]          send a file (no need to write the full path if the file is in working directory
        -r                                  start receiving files
java -jar lans.jar arg1   arg3

argv2 is missing, and I don't know why.

I don't write much C code. Any help?

Upvotes: 0

Views: 195

Answers (3)

pmg
pmg

Reputation: 108978

Let's say, as a thought experiment (there is no rule about it) that argv[0], argv[1], ... are all contiguous in memory...

So you have somewhere in memory the data

    // 0 is the '\0' string terminator
    executable.exe0arg10arg20arg30 ...
    ^              ^    ^    ^ argv[3]
    ^              ^    \----  argv[2]
    ^              \---------  argv[1]
    \------------------------  argv[0]

and then your code

    char* option = argv[1];
    strcat(option, space);

Note that the pointers argv[] did not change

    // 0 is the '\0' string terminator
    executable.exe0arg1 0rg20arg30 ...
    ^              ^    ^    ^ argv[3]
    ^              ^    \----  argv[2]
    ^              \---------  argv[1]
    \------------------------  argv[0]

argv[2] now point to the '\0' string terminator that was put there after the strcat() operation

    char* ip = argv[2];

ip also points to a '\0' string terminator

Upvotes: 0

klutt
klutt

Reputation: 31306

You're writing where there's no space to write. The buffers in argv are exactly as long as they need to be. Or well, that's the only thing you can count on. You can never safely concatenate to them. And in general, it's a good idea to consider them read only.

Here is a snippet to allocate enough for all arguments:

int main(int argc, char **argv) {
    int totlen = 0;
    char *buf;

    for(int i=0; i<argc; i++) 
        totlen += strlen(argv[i]) + 1; // +1 for space

    buf = malloc(totlen + 1); // +1 for zero terminator

    if(!buf) exit(1); // If malloc failed

    buf[0] = 0; // Or else first strcat may cause trouble

    for(int i=0; i<argc; i++) {
        strcat(buf, argv[i]);
        strcat(buf, " ");
    }

    printf("%s\n", buf);

    free(buf);
}

After this, buf will be big enough to hold all arguments passed to the program with a space between each. The program will print all the arguments passed to it.

Upvotes: 2

Manthan Tilva
Manthan Tilva

Reputation: 3277

  1. Add some extra length to array command
  2. Use direct value from argv to prepare command.
char command[1024] = "java -jar lans.jar ";
......
else if (argc == 4) {
    strcat(command, argv[1]);
    strcat(command, space);
    strcat(command, argv[2]);
    strcat(command, space);
    strcat(command, argv[3]);
    printf(command);
    system(command);
}
.....

Upvotes: 1

Related Questions