Error: Must have class type - c++

I need to create a list of contacts and I keep getting this error in my code: expression must have class type.
Here's the code:
#include<iostream>
#include<string>
using namespace std;
class PhoneApp {
public:
string FirstName;
string LastName;
string PhoneNumber;
string EmailID;
PhoneApp() {
FirstName = "";
LastName = "";
PhoneNumber = "";
EmailID = "";
}
void addContact(){
cout << "Enter your contact's first name: ";
cin >> FirstName;
cout << "Enter your contact's last name: ";
cin >> LastName;
cout << "Enter your contact's phone number: ";
cin >> PhoneNumber;
cout << "Enter your contact's email address: ";
cin >> EmailID;
}
void displayContact(){
cout << "Here's your contact details: " << endl;
cout << "FirstName: " << FirstName << endl;
cout << "LastName: " << LastName << endl;
cout << "PhoneNumber: " << PhoneNumber << endl;
cout << "EmailID: " << EmailID << endl;
}
};
int main(){
PhoneApp myPhoneApp[50];
int index = 0;
while(1){
cout << "Press 1 to add contacts" << endl;
cout << "Press 2 to search for a contact" << endl;
cout << "Anything else to quit" << endl;
int choice;
cin >> choice;
switch(choice){
case 1:{ myPhoneApp[index].addContact();
index++;
break;}
case 2: { cout << "Enter a first name to search for: " << endl;
string search = "";
cin >> search;
for (int i = 0; i < index; i++) {
if(myPhoneApp[50].FirstName[i].compare(index) == 0);
break;
}
}
default: exit(1);
}
}
system("pause");
return 0;
}
The error pops up at
if(myPhoneApp[50].FirstName[i].compare(index) == 0
What exactly is the problem here and how do I fix it?
Thanks for the help

There are multiple errors in your code, but the one that you are pointing to is as follows:
myPhoneApp[50].FirstName is a string
Strings consist of characters. You access characters in a string using a subscript operator [i]
Characters are primitives.
You can access members using a dot . on classes and structures, but not on primitives
Since myPhoneApp[50].FirstName[i] is a char, and since char is a primitive, using a dot on it is invalid.

cout << "Enter a first name to search for: " << endl;
string search = "";
cin >> search;
for (int i = 0; i < index; i++) {
if(myPhoneApp[i].FirstName.compare(search) == 0) {
//do stuff
break;
}
}
Several things were going wrong.
First off, you need to compare the entire FirstName string to search, not individual characters of FirstName.
Second, you need to iterate through the contacts in myPhoneApp[], not just keep checking different characters of the FirstName string in index 50, which isn't even necessarily set.
Third, no string.compare() overloads take a single int as an argument. What you're looking for is the method to compare two strings, which is what my answer will do.
Fourth, an issue you didn't get to yet... you had a semicolon after your if statement, so regardless of the condition of the if statement, nothing really executes... and you'd just hit that break; after a single iteration, no matter what.
dashblinkenlight's answer explains why the error message was what it was, mine shows you how to fix your program.

There are several small things coming together here to cause you a problem.
if(myPhoneApp[50].FirstName[i].compare(index) == 0);
break;
Firstly: You have a stray semicolon on the end of the "if" line
if();
means "do the test, and then forget about it. always do the thing on the next line".
Secondly, you are only ever checking one element of your contacts list
myPhoneApp[50]
surely you mean't
myPhoneApp[i]
Next, myPhoneApp[50].Firstname resolves to a single instance of std::string, you then try to index the letters in that name and compare them with the number of entries in your index.
myPhoneApp[50].FirstName[i].compare(index)
What you presumably mean is
if(myPhoneApp[i].FirstName == search)
break;
---- Edit ----
You've given your member variables of "myPhoneApp" upper-camelcase names, just like your class names. This is going to confuse you, and it means you can't name your member variables to match their type:
PhoneApp PhoneApp;
is a compile error.
A common practice is to give member variables distinctive names by adding a prefix ("m_" for member) or suffix (some places add "_" to indicate a member variable).
E.g.
class PhoneApp {
public:
string m_FirstName;
string m_LastName;
string m_PhoneNumber;
string m_EmailID;
PhoneApp() {
m_FirstName = "";
m_LastName = "";
m_PhoneNumber = "";
m_EmailID = "";
}
};
or "m_firstName", "m_lastName" etc.

Related

When I try to use cin in my C++ program, it throws a strange exception

So in the program I'm currently writing, the user is supposed to add people to a vector by inputting their names and partisan identities. However, I have been unable to make the code that actually stores the input work. The program first prompts the user for a name; then, once the user gives a name, it prompts the user again for a partisan identity. Whenever I enter more than one word for the name (e.g. "John Smith"), instead of accepting the input, the program throws this exception.
It also gives this error when I enter "D" or "R" in response to the second prompt, no matter how I respond to the first prompt. Does anyone have an idea what I'm doing wrong here? Here's the code I've written so far:
#include "DelibDem.h"
#include <stdio.h>
#include <vector>
//initializing variables
using namespace std;
bool continue_ = true;
string name = "";
string partyID = "";
int numD = 0;
int numR = 0;
int difference = 0;
int vectorSize = 0;
int newVectorSize = 0;
struct person{
string Name;
string PartyID;
string equivalentName;
string equivalenceClass;
};
vector<person> Sample;
int main()
{
//user adds people to the vector. I have not yet implemented the code that actually adds the people specified by the user yet, because I am still trying
//to figure out why my cin code is not working.
while (continue_ == true) {
string personName;
string personPartyID;
cout << "Enter a person's name: ";
cin >> personName;
cout << "Enter the person's party ID (D or R): ";
cin >> personPartyID;
if (personPartyID == "D") struct person inputtedPerson = { personName, personPartyID, NULL, "Republicans" };
else struct person inputtedPerson = { personName, personPartyID, NULL, "Democrats" };
cout << "Do you wish to add more people? (Y/N) ";
string answer;
cin >> answer;
if (answer == "N") continue_ = false;
}
//The number of Democrats in the sample is stored in numD. The number of Republicans is stored in numR.
for (auto& element : Sample)
{
if (element.PartyID == "D") numD++;
else numR++;
}
//print the number of Democrats and Republicans
cout << numD;
cout << numR;
//print the properties of each element in the sample
for (auto& element : Sample)
{
cout << element.Name << endl;
cout << element.PartyID << endl;
cout << element.equivalentName << endl;
cout << element.equivalenceClass << endl;
cout << "\n";
}
return 0;
}

trouble understanding if statement with strings

i've started learning c++ today.
Now i think that i've got the basics, i couldn't get with this program i'm trying to execute.
Basically all program need to do is, output the user first name, and last name.
Now i got it to work, but i want that if the user input a random number, the program won't execute, and output "Only Text allowed. Please enter your name again: "
also, how do i create space between the first and last name?
would appreciate help. thanks!
this is the code:
int main()
{
int Num;
string First;
string Last;
cout << "Type in your first name please:";
cin >> First;
if (not sure what to declare here)
{
cout >> "No numbers allowed. only Text.";
}
cout << "Type your last name please:";
cin >> Last;
cout << "your full name is:" << " " << First + Last;
}
You will need to search the string for digits.
Here is one method to find numeric digits in a string. There are many others.
static const char digits[] = "0123456789".
if (First.find_first_of(digits) != std::string::npos)
{
cout << "First name has at least one digit.\n";
}
Edit 1:
If that is not easily understood, here is a more basic version:
const unsigned int length = First.length();
for (unsigned int i = 0; i < length; ++i)
{
const char c = First[i];
if (std::isdigit(c))
{
std::cout << "Name has a digit, at position " << i << "\n";
break;
}
}

How can I find in an array of objects the main actor I need

This is my task:
I have done half of my code, but I'm struggling because I'm a beginner in OOP and I'm not sure how I can find movie where main_actor is Angelina Jolie.
for (int i = 0; i < n; ++i)
{
string name;
int year;
string prod;
string actor;
cout << "\nenter the film name " ;
cin >> name;
cout << "\nenter the production year ";
cin >> year;
cout << "\nenter the producer name ";
cin >> prod;
cout << "\nenter the actor name ";
cin >> actor;
obs[i].SetName(name);
obs[i].SetYearP(year);
obs[i].SetProducer(prod);
obs[i].SetMaina(actor);
if (actor == "Angelina Jolie")
{
cout << "The movie who has main actor Angelina Jolie is" << name << endl;
} // Đ¢his is my attempt.
}
}
You need to make a function that loops over your array and checks the main-actor:
bool findFilm(Film* films, int numFilms, string actor)
{
bool found = false;
for (int i = 0; i< numFilms; i++) {
if(!actor.compare(0, films[i].GetyMaina().length(), films[i].GetyMaina()){
cout<<"Film "<<films[i].GetName()<<" has main actor "<<actor<<"\n";
found = true;
}
}
return found;
}
The first thing you should do is using C++ containers like std::vector, std::array instead of raw array. And of course, then you should fill them.
std::vector<Films> films;
std::array<Films, 100> films;
The seconds thing is, you should delete "Films() = default;" part. That declaration changes everything in C++.
After these changes, you will be able to use containers' template member functions and algorithm functions (like find(), find_if(), count() etc.) to get what you need.
#include <algorithm>
If you are not able to do these changes, simply you can do it by looping:
for(auto film : films){
//comparisons, if checks, returns
}
Please use getline() function for user input because cin >> name will save from name Angelina Jolie only Angelina. Because it is reading only whole words not including white space.
To use function getline() put this after #include<cstring>
#include <string>
So use getline like this :
cout << "\n enter the actor name ";
std::getline (std::cin,actor);
Another problem is that you need cin.ignore() between two inputs. Because you need to flush the newline character out of the buffer in between.
Before loop ask for data like this :
cout << "how many films ";
cin >> n;
cin.ignore();
In loop like this :
cout << "\n enter the film name ";
getline(cin, name);
cout << "\n enter the production year ";
cin.ignore();
cin >> year;
cout << "\n enter the producer name ";
cin.ignore();
getline(cin, prod);
cout << "\n enter the actor name ";
getline(cin, actor);
b) (put this function in your class in public section right after string GetMania() ):
static void FindFilm(Film arr[], int cntFilms, string actor)
{
for (int i = 0; i < cntFilms; i++)
{
if (arr[i].GetMaina() == "Angelina Jolie")
cout << "The movie who has main actor Angelina Jolie is" << arr[i].GetName() << endl;
}
}
And from main call it like this right after loop.
string actor = "Angelina Jolie";
Film::FindFilm(obs, n, actor);
Also it's better if you write escape sequence (or special character) for new line (\n) to the end of output message. Like this :
cout << "The name of movie: \n" << name;

How to check if char doesnt exist in a string

Say we have the user input a name that is a string "william" and then the user enters the character that they want to find the index of.
using namespace std;
string name;
char characterToFind;
cout << "Enter a name ";
cin >> name;
cout << "Enter a character to find ";
cin >> characterToFind;
We then want to find the index of the character in the name string array.
for (int j = 0; j < name.length(); j++) {
if (name[j] == characterToFind) {
cout << "char is at index: " << j << endl;
}
}
How do I then check if the inputted character doesnt exist in the name string array? I try to do the following:
if (characterToFind != name.find(characterToFind)) {
cout<< "doesnt exist" << endl;
}
The if statement always seems to be true and runs the code even if the character that was inputted existed in the name string array.
The problem with my approach was that I was doing was that in the if condition i was checking a 's' char vs a index position of an array.
instead, doing:
if (name.find(characterToFind) == std::string::npos) {
cout << "doesnt exist" << endl;
}
this is checking if the character input is equal to a position that doesnt exist! This is true so it tells the user that the character entered does not exist.

Beginner's C++ program for a class

the assignment is the basic "cin a full name" and then "retrieve First Middle Last" bit, where you create a program that asks the user to type in their full first name into a single string and the programs picks apart the name and outputs it organized seperately. this is what i wrote:
#include <iostream>
#include <string>
using namespace std;
int main()
{
string name;
int index;
index = name.find(' ');
cin >> name;
cout << "First name: " << name.substr(0, index) << endl;
name = name.substr(index+1, name.length()-1);
index = name.find(' ');
cout << "Middle Name: " << name.substr(1, index) << endl;
name = name.substr(index+1, name.length()-1);
cout << "Last name: " << name;
return 0;
}
the code just wont seperate them right, and will not redefine 'name' correctly.
It always just bounces back to the beginning of the string.
any help for a newbie?
here's an example output:
Teenage Wonder Land
First name: Teenage
Middle Name: eenag
Last name: Teena
Process returned 0 (0x0) execution time : 7.942 s
Press any key to continue.
You wont' find anything before type your in console and sbustr should read from index 0
string name;
int index;
//index = name.find(' '); // comment out, name is empty, you won't find anything
cin >> name;
index = name.find(' '); // now you can find first space
cout << "Middle Name: " << name.substr(0, index) << endl;
// ^
Or just use std::stringstream
#include <sstream>
std::stringstream ss(name);
std::string token;
int i = 0;
while(ss >> token)
{
switch(i)
{
case 0:
std::cout << "First name: " << token << std::endl;
break;
case 1:
std::cout << "Middle name: " << token << std::endl;
break;
case 2:
std::cout << "Last name: " << token << std::endl;
break;
default:
break;
i++;
}
}
You clearly can't search for something in name before you assign it a value, which is what you're doing now:
string name;
int index;
index = name.find(' '); // No value assigned to name yet - nothing to search
cin >> name; // Now you're giving it a value (too late)
Instead, assign and then try to find a value:
string name;
int index;
cin >> name; // Assign a value first
index = name.find(' '); // Now try to find something in it
I think you should use std::getline to get the entire line of text at once. Currently you are only reading in the first word (>> operator will only extract text up to the next whitespace character).
std::string name;
if (std::getline(cin, name))
{
// extraction successful, "name" should contain entire line
}
Then, you can use one of the other answers in this question or continue with your own approach.
The extraction operator >> for istream will grab all non-whitespace characters in the buffer until it encounters a whispace.
So your input here:
Teenage Wonder Land
contains 3 whitespaces including the invisible newline at the end when you hit enter. From this you should be able to figure out what the following does:
cin >> name;
Hint: name doesn't contain the entire line you just entered.
#include <iostream>
#include <string>
using namespace std;
string getnext(const string &full, const string &delim, size_t &beg) {
size_t prev = beg;
beg = full.find(delim, beg);
if (beg != string::npos)
return full.substr(prev, beg-prev);
return full.substr(prev, full.length()-prev);
}
int main()
{
string name, temp, error = "NameError: Enter first, middle, last";
size_t index = 0;
getline(cin, name); //Get the full name
temp = getnext(name, " ", index); //Get first name
if (index == string::npos) {
cout << error;
return -1;
}
cout << "First name: " << temp << endl;
temp = getnext(name, " ", ++index); //Get middle name
if (index == string::npos) {
cout << error;
return -1;
}
cout << "Middle Name: " << temp << endl;
temp = getnext(name, " ", ++index); //Get last name
cout << "Last name: " << temp << endl;
return 0;
}