views:

40

answers:

1

I realize that each argument passed from the command line is stored as a string in 'char *argv[]'

I'd like to pass

$ progname array[500]

and pull the string from argv[1] subsequently specifying an array based on what I read in.

Any ideas?

A: 

Well from your new comment, I will try to answer the question. I am doing most of this to show you one possibility, my code will have some makeshift string parsing and not much error checking, it's just to give you an idea of how you can do it.

If you wanted the user to specify the size of an array you wanted to make, that is doable.

#include <iostream>
#include <cstdlib>

int main(int argc, char **argv)
{
   if (argc < 2) // the program's name is the first argument
   {
      std::cerr << "Not enough arguments!\n";
      return -1;
   }

   int arraySize = std::atoi(argv[1]);

   char *cArray = new char[arraySize];

   delete [] cArray;

   return 0;
}

If you run the above program and pass it argument 500, it would allocate a memory block to store up to 500 * sizeof(char).

If you wanted the user to actually give you the name of the array and its size, that's a little different - you can not create a variable name at runtime. One thing you could do is map strings to arrays.

Here's a program that would accept an argument list consisting of arguments like hello[100] and create a mapping of hello to a pointer to a block of space for 100 elements.

#include <iostream>
#include <cstdlib>
#include <map>
#include <string>
#include <boost/shared_ptr.hpp>

int main(int argc, char **argv)
{
    std::map<std::string, boost::shared_ptr<char> > arrayMap;

    for(int i = 1; i < argc; ++i)
    {
       // arguments are like 'hello[500]', 'array[100]
       std::string s = argv[i];
       std::size_t posOpen = s.find("[");
       std::size_t posClose = s.find("]");

       std::string name = s.substr(0, posOpen);

       std::string size = s.substr(posOpen, posClose);

       // remove the '[' and ']' characters
       size.erase(0, 1);
       size.erase(size.length()-1, 1);

       std::cout << name << " " << size << std::endl; 

       // allocate our new array and wrap a shared_ptr around it
       boost::shared_ptr<char> cptr(new char[std::atoi(size.c_str())]);

       arrayMap[name] = cptr;

    }

    // now you can access the arrays 'by name'

    return 0;
}

If you ran the above code and passed it a list of arguments, such as hello[500] array[1000] somelist[100], it would create 3 heap-allocated blocks and map names to them: "hello" would map to a pointer to a block of 500 * sizeof(char), "array" would map to a pointer to a block of 1000 * sizeof(char), and "somelist" would map to a pointer to a block of 100 * sizeof(char) bytes.

There is a problem with that code above though - it does not keep track of the number of bytes allocated for each pointer's pointed-to block, which makes it rather worthless for you. One alternative would be to map the names to boost::array<Typename T, std::size_t n>, which will be boost's fixed-size array class that keeps track of its size and has a size() member function.

birryree