0

Is there a way in C to store the whole command line options and arguments in a single string. I mean if my command line is ./a.out -n 67 89 78 -i 9 then a string str should be able to print the whole command line. Now, what I am able to do is to print values in different vector forms.

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


int main(int argc, char* argv[]) {
 int opt;

for(i=0;i<argc;i++){
printf("whole argv was %s\n", argv[i]);
}

while((opt = getopt(argc, argv, "n:i")) != -1) {
switch (opt){
    case 'n':
             printf("i was %s\n", optarg);
             break;

    case 'i':
             printf("i was %s\n", optarg);
             break;
      }
   }
  return 0;
 }

I want this, as optarg only is printing my first argument and I want all the arguments to be printed, so I want to parse it after storing it in string.

2
  • Not in general, no, since it's hard to reverse-engineed whatever the shell (which is usually what invokes your program) got from the user. For instance ./a.out foo vs ./a.out "foo"; your program can't know if the user quoted an argument. Commented Aug 15, 2013 at 15:07
  • 2
    Since you're on Linux, you can read /proc/self/cmdline Commented Aug 15, 2013 at 15:24

3 Answers 3

2

What you can do is to loop over argv and build a string with strcat

char* CommandLine = 0;
unsigned int CommandLineLength = 0;
unsigned int i = 0;

for (i = 0; i < argc; i++) {
    CommandLineLength += strlen(argv[i]) + 3; // Add one extra space and 2 quotes
}

CommandLine = (char*) malloc(CommandLineLength + 1);
*CommandLine = '\0';

// Todo: Check if allocation was successfull...

for (i = 0; i < argc; i++) {
    int HasSpace = strchr(argv[i], ' ') != NULL;
    if (HasSpace) {
        strcat(CommandLine, "\"");
    }
    strcat(CommandLine, argv[i]);
    if (HasSpace) {
        strcat(CommandLine, "\"");
    }
    strcat(CommandLine, " ");
}
// Do something with CommandLine ...
free(CommandLine);
Sign up to request clarification or add additional context in comments.

16 Comments

you should add at least one blank between two arguments
Of course, one space charcter should be included. If one command line argument itself contains spaces, the command line should be quoted with "".
don't want to annoy you, but now CommandLineLength += strlen(argv[i]); should be changed to ... + 3; --- one for the blank and two for the quotation (or you check twice) :-)
@bkausbk your code gave me the following errors: In function ‘main’: fun27.c:21:15: error: ‘new’ undeclared (first use in this function) fun27.c:21:15: note: each undeclared identifier is reported only once for each function it appears in fun27.c:21:19: error: expected ‘;’ before ‘char’ fun27.c:25:5: warning: passing argument 2 of ‘strchr’ makes integer from pointer without a cast /usr/include/string.h:235:14: note: expected ‘int’ but argument is of type ‘char *’
Use strncat instead of strcat. strcat is usually poisoned by source control rules or makefiles, because it has potential to introduce buffer overflow vulnerabilities. strncat takes a size argument, allowing you to ensure that the buffer doesn't overflow.
|
0

It depends on the platform.

In Windows, you can use GetCommandLine().

Comments

-1

Simply write a function like this:

char * combineargv(int argc, char * * argv)
{
    int totalsize = 0;
    for (int i = 0; i < argc; i++)
    {
       totalsize += strlen(argv[i]);
    }
    // Provides space for ' ' after each argument and a '\0' terminator.
    char *ret = malloc(totalsize + argc + 1);
    if (NULL == ret)
    {
        // Memory allocation error.
    }
    for (int i = 0; i < argc; i++)
    {
        strcat(ret, argv[i]);
        strcat(ret, " ");
    }
    return ret;
}

This will simply combine all of them, placing spaces between args

Update: I have modified the original to eliminate the buffer overflow issue.

10 Comments

why totalsize + 15?
I gave it a small buffer zone, since we are adding spaces.
and take look at the comments to bkausbk's answer. Reconcatanation of arguments is not trivial, if it shall be correct under all circumstances.
because you are still using the [], malloc() is a function. I am editing the original answer to reflect the malloc
WARNING: This has a HUGE potential bug. You call strcat passing the buffer you just got back from malloc. A buffer which may contain GARBAGE. Since strcat will look for the first '\0' (which may not be there in your buffer) your function could end up overwriting random memory. Please either memset the entire allocated buffer so it's full of null bytes or manually set ret[0] = 0; before you loop, copying arguments. @user227666 please be very careful if you do use this function.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.