CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 3 of 3
  1. #1
    Join Date
    Apr 2010
    Posts
    19

    Using a string/enum to access int Matrix[X] ?

    Hola code gurus,

    I’m wondering if there’s a way to use a string to access a specific item in a matrix of int[X].

    I have a program which uses enums as iterators to reference a large amount of data. To select an item in the matrix, the user will enter a string, which is also an enum, which also must serve as an iterator for something in the matrix. Here is a toybox example:

    ====================================================================
    #include <iostream>
    #include <string>
    using namespace std;

    enum NyNumbers { First, Second, Third, Forth, LAST_VALUE };

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

    int Matrix[LAST_VALUE] = { 1, 3, 7, 12 };

    cout<<"Matrix[ atoi("<<argv[1]<<") ]: ";
    cout<<Matrix[ atoi(argv[1]) ]<<"\n";

    return 0;
    }
    ====================================================================

    The idea is the user executes the program by typing “./RUN First” to print out the first element in the MyNumbers array, “./RUN Second” to access the second, and so on. I can’t use static numbers for the iterator. (i.e., “./RUN 1”) I must reference by enum/string.

    When run, the output of this problem is thus:

    ====================================================================
    user@debian$ ./RUN Second
    Matrix[ atoi(Second) ]: 1
    user@debian$
    ====================================================================

    BTW, if I change line 12 to this…

    ====================================================================
    cout<<Matrix[ argv[1] ]<<"\n";
    ====================================================================

    …the error message is this…

    ====================================================================
    user@debian$ make
    g++ -g -Wall -ansi -pg -D_DEBUG_ Main.cpp -o exe
    Main.cpp: In function `int main(int, char**)':
    Main.cpp:12: error: invalid types `int[4][char*]' for array subscript
    make: *** [exe] Error 1
    user@debian$
    ====================================================================

    …which isn’t unexpected. Any idea how to imput the enum as argv[1]?

    Many thanks!
    -P

  2. #2
    Join Date
    Jan 2009
    Posts
    596

    Re: Using a string/enum to access int Matrix[X] ?

    The string representations of the enum:
    Code:
    enum NyNumbers { First, Second, Third, Forth, LAST_VALUE };
    are not present in the final executable. You can prove this to yourself by compiling the code as it is and running md5sum on it. Then correct the spelling of 'Forth' to 'Fourth' , compile it again and rerun md5sum. You will get the same result, showing the executables are identical.

    So to solve your problem you need to do one of these options, depending upon your experience/needs:

    1) Have a std::vector of std::string with the relevant values. Then loop through these to find the correct string and output the corresponding value of the Matrix array

    2) Have a std::vector of std:: pair, with one value of the pair being the strings and the second value being the values of Matrix. Again, search for the string and output the relevant Matrix value

    3) Create a std::map with the keys being the strings and values being the Matrix values.

  3. #3
    Join Date
    Jun 2009
    Location
    France
    Posts
    2,513

    Re: Using a string/enum to access int Matrix[X] ?

    C++ doesn't do that, it is strongly typed. You can't just throw variables around and hope it will work.

    What Peter said.

    Also, be careful with enums and mainspace scope. Your are using the "LAST_VALUE" trick, but at the same time, without scope, you are creating a global "LAST_VALUE" token, and ruining it for everyone else.

    You can, for example, scope your enum in a namespace:

    Code:
    namespace NyNumbers
    {
      enum NyNumbers
        {First, Second, Third, Forth, LAST_VALUE };
    }
    This way, you have to write "NyNumbers::LAST_VALUE". You can also use a struct instead of a namespace. There subtle differences. If you have access to C++11, you can also use enum classes.

    That said, I'd question the entire enum approach. It seems that all you really want is to store an index, and be able to build it from text:

    Code:
    #include <iostream>
    #include <string>
    #include <unordered_map>
    #include <cstdlib>
    
    //The string 2 enum
    std::unordered_map<std::string, size_t> String2NyNumbers =
    {
      {"First", 0},
      {"Second", 1},
      {"Third", 2},
      {"Forth", 3}
    };
    
    int main(int argc, char* argv[])
    {
      int Matrix[] = { 1, 3, 7, 12 };
    
      auto it = String2NyNumbers.find(argv[1]);
      if(it == String2NyNumbers.end())
        {return EXIT_FAILURE;}
    
      size_t index = static_cast<size_t>(it->second);
      std::cout << "The " << argv[1] << " index at " << index << " is " << Matrix[index] << std::endl;
    
      return 0;
    }
    Is your question related to IO?
    Read this C++ FAQ article at parashift by Marshall Cline. In particular points 1-6.
    It will explain how to correctly deal with IO, how to validate input, and why you shouldn't count on "while(!in.eof())". And it always makes for excellent reading.

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured