Save argv to vector or string
Asked Answered
R

2

14

I need to save all arguments to a vector or something like this. I'm not a programmer, so I don't know how to do it, but here's what I've got so far. I just want to call a function system to pass all arguments after.

#include "stdafx.h"
#include "iostream"
#include "vector"
#include <string>
using namespace std;

int main ( int argc, char *argv[] )
{
       for (int i=1; i<argc; i++)
       {
           if(strcmp(argv[i], "/all /renew") == 0)
           {
                 system("\"\"c:\\program files\\internet explorer\\iexplore.exe\" \"www.stackoverflow.com\"\"");
           }
           else
              system("c:\\windows\\system32\\ipconfig.exe"+**All Argv**);
       }

       return 0;
}
Randellrandene answered 15/6, 2011 at 17:15 Comment(1)
Note: argv contains the tokens separated by whitespace, so I doubt it will ever contain both /all and /renew.Swagsman
C
77

i need to save all arguments to a vector or something

You can use the range constructor of the vector and pass appropriate iterators:

std::vector<std::string> arguments(argv + 1, argv + argc);

Not 100% sure if that's what you were asking. If not, clarify.

Cord answered 15/6, 2011 at 17:16 Comment(13)
(silently replaces a for loop in his own code by a range constructor in the initializer list. Repeat after me: "a class constructor shall not do any work, a class constructor must not do any work")Calque
@rubenvb: why blindly comply to a principle that asks you to write more code for no apparent reason?Swagsman
@Calque - 1) why must a class constructor do no work? 2) Perhaps you'd prefer vector<string> args; args.insert(args.end(), argv+1, argv+argc);Phosphorate
@Fred: from OP's use case, it seems the required output is not the vector itself, but a concatenation of the arguments...Swagsman
@Bo, @André, @Rob: you all misunderstood me. I had a class with a constructor that filled a vector through a for loop, while I could have done the same thing through the correct vector constructor call. I do not want to build vector myself, I do not comply blindly to that principle; my code has not seen the need to do otherwise, and 1) it prevents accidentally throwing exceptions if you don't catch these inside the constructor code block. 2) good suggestion, but irrelevant due to aforementioned misunderstanding. My apologies for not being clear enough.Calque
@rebenvb: the exception being thrown out of the constructor is a feature! Why would you want a partially constructed object?Swagsman
@André: I've read all the discussions here on SO on the subject, and frankly, I currently don't use exceptions except when either the program runs out of memory (a situation I don't want to handle gracefully) or I made some stupid programmer error. All the others are considered bugs that need to be fixed. I understand the pro's of doing what you say, just haven't met the need to use it.Calque
@RedX Because vector has a range constructor, and because char* is convertible to string?Cord
argv NOT argv + 1Mitosis
@DBJDBJ argv[0] is usually the name and path of the executable, which in most cases you don't care about.Cord
@Cord Why did you write argv + argc and not just argc. Doesn't argv represent a neutral element here (0)?Western
@JonathanKomar Because the vector constructor requires two iterators, in this case char pointer pointers. argc is just an int, whereas argv and argv+argc are char**s.Cord
@Cord So you‘re taking advantage of implicit type conversion...Western
Z
0

To build string with all argument concatenated and then run a command based on those arguments, you can use something like:

#include <string>
using namespace std;
string concatenate ( int argc, char* argv[] )
{
    if (argc < 1) {
        return "";
    }
    string result(argv[0]);
    for (int i=1; i < argc; ++i) {
        result += " ";
        result += argv[i];
    }
    return result;
}
int main ( int argc, char* argv[] )
{
    const string arguments = concatenate(argc-1, argv+1);
    if (arguments == "/all /renew") {
        const string program = "c:\\windows\\system32\\ipconfig.exe";
        const string command = program + " " + arguments;
        system(command.c_str());
    } else {
        system("\"\"c:\\program files\\internet explorer\\iexplore.exe\" \"www.stackoverflow.com\"\"");
    }
}
Zanze answered 15/6, 2011 at 17:29 Comment(6)
Note: for a better string concatenation, use stringstream instead.Swagsman
@André: and for better performance generally (not that this particular use case will slow you down much...)Calque
Edit: fixed bug in concatenation, spaces are required.Swagsman
@Andre Caron Why is stringstream better for concatenation? std::string supports concatenation directly; std::ostringstream is for formatting output.Brocky
@James: the difference is not as explicit when using operator+= with the string because most implementations give it a nice allocation policy (they grow quick). However, repeated use of operator+ will likely perform one allocation per concatenation.Swagsman
@Andre Caron I'm not sure I understand your point. The natural way of concatenating strings is the + operator (or +=). Anything else is obfuscation.Brocky

© 2022 - 2024 — McMap. All rights reserved.