1

Say I have a structure as follows

struct stock{
    string ticker;
    double price;
    double volume;
    double eps;
};

If I want to output one of the variables such as price when asked for it would I have to do a large if/else or switch statement to match up the user input with the member or is there a more elegant way to do it because I know stock.userInput does not work.

Cheers and hth. - Alf
  • 142,714
  • 15
  • 209
  • 331
  • Related question: http://stackoverflow.com/questions/2911442/access-variable-value-using-string-representing-variables-name-in-c – jogojapan Oct 22 '12 at 03:07
  • 1
    Better understanding the question, try a `std::map`. Since the second can be a number of types, perhaps something like Boost's Any for the second type would be useful. – chris Oct 22 '12 at 03:19

4 Answers4

0
struct stock s1;
cout<<" price is:"<< s1.price;
Ravindra Bagale
  • 17,226
  • 9
  • 43
  • 70
0

there's no special keyword to find your variable(sorry to burst your bubble), You would have to use a logical statement. It would go along:

cout << "What would you like to see? (1)Price (2)etc...etc...";
cin >> input;
switch(input)
{
    case 1:
        cout << Obj.Price;
    break;
    case 2:
        cout << //....
    break;
}

I personally like using keys and a switch statement, it tends to be a lot cleaner and easier to go back and modify later in the program.

Syntactic Fructose
  • 18,936
  • 23
  • 91
  • 177
0

If you want to get rid of the large switch/if statement, you can use map with string and a pointer-to-member. Assuming your stock struct, you can use:

Define the map (for doubles here) and initialize it:

std::map<std::string,double stock::*> double_members;
double_members["price"]=&stock::price;
double_members["volume"]=&stock::volume;
double_members["eps"]=&stock::eps;

And use it to look up some values:

stock stock1;
std::string input;
std::cin >> input;
if (double_members.find(input)!=double_members.end()) 
    std::cerr << "Value for " << input << " is: " << stock1.*double_members[input] << std::endl;
else
    std::cerr << "There's no field called " << input << std::endl;

It's limited to a single type, but you can't have a statement like std::cerr << A; and have A's type resolved during runtime. If you care only about string (or any other, but always the same) representation of the values, then you can wrap maps for different types in a class that searches all of them and outputs the value converted to a string (or something).

But it's probably easier to have the if statement, unless the struct is really big.

v154c1
  • 1,698
  • 11
  • 19
0

If it's okay with you that it doesn't work with g++ 4.7.1 and earlier (but does work with Visual C++ 11.0 and later), then like …

#include <sstream>      // std::ostringstream
#include <string>       // std::string
using namespace std;

struct Stock
{
    string ticker;
    double price;
    double volume;
    double eps;

    string toString() const
    {
        ostringstream stream;
        stream
            << "Stock("
            << "ticker='" << ticker << "', "
            << "price=" << price << ", "
            << "volume=" << volume << ", "
            << "eps=" << eps
            << ")";
        return stream.str();
    }

    Stock(): ticker(), price(), volume(), eps() {}
};

#include <iostream>
#include <regex>
#include <stdexcept>
#include <stdlib.h>

bool err( string const& s )
{
    cerr << "!" << s << endl;
    exit( EXIT_FAILURE );
}

string lineFromUser( string const& prompt )
{
    string line;
    cout << prompt;
    getline( cin, line )
        || err( "oh my, failed to read line of input" );
    return line;
}

void cppMain()
{
    Stock stock;
    stock.price = 1.23;

    string const s = stock.toString();
    cout << s << endl;
    string const fieldname = lineFromUser( "Which field u want? " );
    regex const valuespec( fieldname + "\\s*\\=\\s*([^,\\)]*)" );  // 
    smatch what;
    if( regex_search( s, what, valuespec ) )
    {
        cout << "As we all know already, " << what.str() << "." << endl;
    }
    else
    {
        cout
            << "!Sorry, there's no field named '"
            << fieldname << "'"
            << endl;
    }
}

int main()
{
    try
    {
        cppMain();
        return EXIT_SUCCESS;
    }
    catch( exception const& x )
    {
        cerr << "!" << x.what() << endl;
    }
    return EXIT_FAILURE;
}

Example usage:


[d:\dev\test]
> foo
Stock(ticker='', price=1.23, volume=0, eps=0)
Which field u want? eps
As we all know already, eps=0.

[d:\dev\test]
> _
Cheers and hth. - Alf
  • 142,714
  • 15
  • 209
  • 331