Retrive Values From Enum - c++

How can i recieve a specific value from an enum from a given index.
enum genre { Pop, Jazz, Classic}; //enum
struct album
{
string album_name;
genre kind;
int track_number;
string tracks[5];
string tracklocation;
};
void main()
{
album x1;
cout<<"Enter genre 0->pop, 1->Jazz, 2->Classic\n";
cin>>temp;
x1.kind=(genre)temp; // typecasting for int to enum
cout<<x1.kind<<endl;
}
When i run this code i just get the integer value i input , instead of the converted enum value
what i need is when user input 0,1 or 2 it needs to be converted using the enum to the relevant genre and saved in the stucture variable.

You can't put the identifiers (names) of an enum to cout. For example, the value of the name Pi in enum, suppose it's set to 3.14. You directly wants the user would type that value, it'll show the string Pi in output stream, but no, it's only within supposed within the code. Enumeration just holds the constants.
By default, your declaration enum {Pop, Jazz, Classic} holds the constant values 0, 1 and 2 respectively.
Rather, you could use arrayed string to get a value. Consider the following example:
struct album {
string album_name;
string genre[3] = {"Pop", "Jazz", "Classic"}; // this one holds 0 = "Pop" ...
int track_number;
string tracks[5];
string tracklocation;
};
And the driver code:
int main(void) {
album x1;
int temp;
std::cout << "Enter genre 0->pop, 1->Jazz, 2->Classic\n";
std::cin >> temp;
std::cout << x1.genre[temp] << endl;
// will display 0 = "Pop", 1 = "Jazz", 2 = "Classic"
return 0;
}

Related

How to copy a Corba struct (containing an "any" type) into a C++ struct

In Corba, I have a struct like so:
module XYZ {
typedef string AttributeName;
struct AttributeColumn {
AttributeName name; // Column attribute name
any data; // Column attribute value
};
typedef sequence <AttributeColumn> AttributeTable;
}
It contains values from a corresponding Sqlite database table which has the following field:
ABC_Name VARCHAR NOT NULL UNIQUE
I want to copy these values into a C++ struct, which consists of the following:
namespace DEF {
typedef std::string AttributeName;
typedef std::vector<std::string> StringCol;
struct AttributeColumn {
AttributeName name; // Column attribute name
StringCol str; // Column values if string
};
typedef std::vector<AttributeColumn> AttributeTable;
}
Here is my attempt:
XYZ::AttributeTable & xyz_table = getAttributeTable (); // This gives me the table containing the data from the database.
int rows = getLength ( xyz_table ); // This gives me the number of rows in the database.
DEF::AttributeTable def_table;
for (int i=0;i<rows;i++) {
def_table[i].name = xyz_table[i].name;
std::cout << def_table[i].name << std::endl;
xyz_table[i].data >>= def_table[i].str;
std::cout << def_table[i].str << std::endl;
}
However, the above does not compile.
I get the following error message:
ERROR: 1> error: no match for ‘operator>>=’ (operand types are ‘CORBA::Any’ and ‘DEF::StringCol’ {aka ‘std::vector<std::basic_string<char> >’})
If I comment out the last two lines in the for loop, then the code compiles, but it crashes.
So, somehow, the copy into the def_table for the "name" field does not work correctly either.
try this :
namespace DEF {
typedef std::string AttributeName;
typedef std::vector<std::string> StringCol;
struct AttributeColumn {
AttributeName name; // Column attribute name
CORBA::Any str; // Column values if string
};
typedef std::vector<AttributeColumn> AttributeTable;
};
because str need to be the same type of data .

How to use protobuf descriptor to read enums

Let's say I have a .proto file with:
message Foo {
optional int32 x = 1;
enum y {
MOBILE = 0;
HOME = 1;
}
optional string z = 3;
}
Then I have this C++ code which prints all the types:
const Reflection *refl = Foo.GetReflection();
const Descriptor *desc = Foo.GetDescriptor();
int fieldCount = desc->field_count();
for(int i=0;i<fieldCount;i++){
const FieldDescriptor *field = desc->field(i);
cout << field->name().c_str() << " the type is "
<<field->type_name()<< ": Type Number "<< field->type() <<endl;
if(field->type()==FieldDescriptor::TYPE_ENUM){
//do something
}
The output is then:
x the type is int32: Type Number 5
z the type is string: Type Number 9
As seen in the output, the enum is skipped, how would I get the field descriptor to parse over the enum as well?
You do not have a field of your Enum type, you have only defined a type. Because of that, your iteration over fields doesn't yield anything related to the enum.
If you add a field of a given type, you will see your enum there.

String in struct in struct in C++

So I've to do another exercise. This time I need to define a struct and a 100-elements array, which will store information about the book (title, author, ID number, price) and a simple function which will print info about all of the books stored. I started with that code:
#include <iostream>
using namespace std;
int main()
{
struct name_surname {string name, surname;};
struct book {string title; name_surname author_name, author_surname; int ID; int price;};
return 0;
}
And, well, what now? How can I store this in an array?
You just create an array of type book or name_surname or whatever you want.
Example:
book arr[100];
arr[0].title = "The last robot";
arr[0].ID = 2753;
Tips:
It's good programming practice if your structs/classes begin with with capital letter, so it's easier to distinguish them and so it is easier to name the variable the same name just without the capital letter. Example.
struct Name_surname
{
string name, surname;
};
Name_surname name_surname[100];
name_surname[0].name = "MyName";
Another tip is that I'd really suggest you learn how to research, this question has been answered millions of times and answers are all over the internet.
Here is my suggestion :
struct book
{
string title;
string name_surname;
string author_name;
string author_surname;
int ID;
int price;
};
struct Database
{
book *array;
void printDatabase()
{
for(int i = 0 ; i < 100 ;i++)
cout<<array[i].title<<endl;
}
Database()
{
array = new string [100];
}
};
Your name structure seems a little confused but creating an array is simply a case of declaring a variable with [] appended to it giving the size.
For example:
struct full_name
{
std::string firstname;
std::string surname;
};
struct book
{
std::string title;
full_name author;
int ID;
int price;
};
int main()
{
// Declare an array using []
book books[100]; // 100 book objects
// access elements of the array using [n]
// where n = 0 - 99
books[0].ID = 1;
books[0].title = "Learn To Program In 21 years";
books[0].author.firstname = "Idont";
books[0].author.surname = "Getoutalot";
}
What do you think about that:
#include <iostream>
using namespace std;
struct book {string title; string name; int ID; int price;} tab[100];
void input(book[]);
void print(book[]);
int main()
{
input(tab);
print (tab);
return 0;
}
void input(book tab[])
{
for (int i=0;i<3;i++)
{
cout<<"\nBook number: "<<i+1<<endl;
cout<<"title: ";cin>>tab[i].title;
cout<<"name: ";cin>>tab[i].name;
cout<<"ID: ";cin>>tab[i].ID;
cout<<"price: ";cin>>tab[i].price;
}
}
void print (book tab[])
{
for (int i=0; i<3; i++)
{
cout<<"\nBook number: "<<i+1<<endl;
cout<<"title: "<<tab[i].title;
cout<<"\nname: "<<tab[i].name;
cout<<"\nID: "<<tab[i].ID;
cout<<"\nprice: \n"<<tab[i].price;
}
}
I've done this with help from some Yt video. It works, but, is there a way to do it better, or just leave it how it is? And I have a question: Why those function parameters? Can't I just say tab[] or something else?
Computer languages are based on general and recursive rules. Just try to experiment and extrapolate with the basic understanding to build seemingly complex stuff. Coming to what you are trying to achieve:
We know, an array can be declared for any data-type (primitive or derived, one might call them POD and ADT).
We know, struct can comprise of any number of elements of any data-types.
Now, we can see that it is just as natural to say MyStruct[] as it is to int[].
It is better to prefer std::array if using modern compiler.

Static int with array C++

I'm trying to static count my driver user. however it always give me same value instead
class Driver {
private:
static int ID;
string name;
public :
void displayDriver(string n) {
cout << ID << endl;
}
void createDriver(string n) {
name = n ;
ID++;
}
}
int Driver::id=0;
int main() {
Driver driver[10];
Driver[0].createDriver("first");
Driver[1].createDriver("second");
Driver[2].createDriver("first");
Driver[0].displayDriver();
Driver[1].displayDriver();
Driver[2].displayDriver();
}
my expected output should be :
1
2
3
but system shows me :
3
3
3
private:
static int ID;
Denotes that ID is shared among Driver instances. Any change to it (from createDriver in your current code) will be reflected in ALL instances. Don't use static field if you want each instance has its own unique field.
Do something like I show here to get the results you expect. The idea is to keep the next counter in ID but every instance to have its own id that get initialized when you create the driver.
class Driver
{
private:
static int ID;
int my_id;
string name;
public :
void displayDriver(string n)
{
cout << my_id << endl;
}
void createDriver(string n)
{
name = n ;
my_id = ID++;
}
}
int Driver::id=0;
int main
{
Driver driver[10];
Driver[0].createDriver("first");
Driver[1].createDriver("second");
Driver[2].createDriver("first");
Driver[0].displayDriver();
Driver[1].displayDriver();
Driver[2].displayDriver();
}
It is because the value of ID gets incremented each time u createDriver("");
(no matter for which Driver[]) as it is a static variable
So u r incrementing ID progressively to 3 in first 3 lines
while displaying value of ID in next 3 lines
To get the expected output
I think u need to try it like this :
Driver[0].createDriver("");
Driver[0].displayDriver();
Driver[1].createDriver("");
.
.
.
So on!
Note that all drivers have the same ID (static field).

I keep receiving -2 as my updated salary

I am doing the following with my program:
1) Write the class definition for a class named Employee with name and salary as employee objects. The class contains two member functions: the constructor and a function that allows a program to assign values to the data members.
2) Add two member functions to the Employee class. One member function should allow any program using an employee object to view the contents of the salary data member. The other member function should allow the program to view the contents of the employee name data member.
3) Add another member function to the Employeeclass. The member function should calculate an employee objects new salary, based on a raise percentage provided by the program using the object. Before calculating the raise, the member function should verify that the raise percentage is greater than or equal to zero. If the raise percentage is less than zero, the member function should display an error message.
4) Write a main function that will create an array of employee objects, assign values to the objects, display the names and current salaries for all objects, ask user for the raise percentage and then calculate and display new salaries for all objects.
However, I receive -2 as my new salary after I input the data from the keyboard. I figured another set of eyes could see what I can't and would highly appreciate if someone can lend a hand, or at least steer me in the right direction. Perhaps it is a logic error, or something wrong with my declarations. Thank you for your time.
#include <iostream>
#include <cstdlib>
#include <string>
using namespace std;
class EMPLOYEE
{
public:
EMPLOYEE();//
EMPLOYEE(string name, int salary);//
public:
string name;//name to be input
int salary;//salary to be input
int percentage_raise;
int updated_salary;
public:
int enter_values();
int output_values();
int NEW_SALARY();
};
//default constructor
EMPLOYEE::EMPLOYEE()
{
name = "";
salary = 0;
}
//constructor with name/salary variables
EMPLOYEE::EMPLOYEE(string NAME, int SALARY)
{
name= NAME;
salary= SALARY;
}
//name and salary to be input...
int EMPLOYEE::enter_values()
{ cout<<"Enter name and salary: ";
cin>> name;
cin>>salary;
return 0;
}
//output
int EMPLOYEE::output_values()
{ cout<<"Name: "<<name<<endl;
cout<<"Salary: "<<salary<<endl;
return 0;
}
//
int EMPLOYEE::NEW_SALARY()
{
if ( percentage_raise >= 0)
{ int updated_salary;
int raise= (salary *percentage_raise)/100;
updated_salary += raise;
}
else if(percentage_raise< 0)
{ cout<<"Error Message"<<endl;
}
return 0;
}
int main()
{
EMPLOYEE employees[100];
EMPLOYEE percent_to_be_raised;
int i;
for(i =0 ;i<100 ; i++)
{ employees[i]=EMPLOYEE();
employees[i].enter_values();
employees[i].name;
employees[i].salary;
// employees[i].NEW_SALARY();
employees[i].output_values();
cout<<"How much should the salary be raised by?"<<endl;
cin>>percent_to_be_raised.percentage_raise;
cout<<"-----------------------------"<<endl;
cout<<employees[i].name <<"'s new salary is "<<percent_to_be_raised.updated_salary<<endl;
}
}
You need to rewrite this quite alot.
A few pointers:
EMPLOYEE percent_to_be_raised;
Is completely off base. The task states that this calculation should be done in an employee member function. I.e. the raise should be performed as
Employee alfred;
std::cin>> alfred.salary;
double raise;
std::cin>> raise;
alfred.raise_salary(raise); // this is what the task asks for.
Use a naming convention.
Employee
is fine for a c++ class with a capitalized class name convention. EMPLOYEE is not; this looks like a macro name.
Member function usually starts with non-capitalized
Employee::new_salary( the_salary );
Follow the examples you have available from the course material.
Of course
employees[i].name;
employees[i].salary;
Does not do anything. Please review your code in detail and start at the first spot you don't understand.
Note that the OP coding style convention is used to assist the OP. I am aware of the proper naming convention for classes, member functions, and class data members (e.g. see the answer by Captain Giraffe for more).
Inside of:
int EMPLOYEE::NEW_SALARY()
{
if ( percentage_raise >= 0)
{ int updated_salary;
int raise= (salary *percentage_raise)/100;
updated_salary += raise;
}
} // added this to close the function properly
there is a locally declared variable, which is typed identically to the public access data member of the same name. What is the intention here?
Most likely it should be coded like so:
int EMPLOYEE::NEW_SALARY()
{
if ( percentage_raise >= 0)
{
int raise = (salary *percentage_raise)/100;
updated_salary += raise;
}
} // added this to close the function properly
There are design considerations for having all class member data public, as well as having an integer for a percentage. From the calculation above, it looks like only values of one, two, three, etc. are allowed for the percentage number. What is the class supposed to do if a raise is 3.75 percent?
The constructor has to set ALL class data members to something meaningful too. For example, the percentage_raise and updated_salary variables are ignored. Most likely the default constructor has to be updated to:
//default constructor
EMPLOYEE::EMPLOYEE()
{
name = "";
salary = 0;
percentage_raise = 0;
updated_salary = 0;
}
The name and salary constructor has to be updated too. It should probably look like (using the style convention posted by the OP):
//constructor with name/salary variables
EMPLOYEE::EMPLOYEE(string NAME, int SALARY)
{
name = NAME;
salary = SALARY;
percentage_raise = 0;
updated_salary = salary;
}