I am working on an assignment which has the following goals:
Store user provided customer info into an array of structs.
Write functions to add, display all or retrieve a customer(s).
I have an issue with writing my findCust (retrieval routine). I would like to prompt the user for a first and last name of any customer, and then to find the relevant customer in the array of customers and print out their information. I'm kind of stuck and not sure how to proceed.
This is what I have so far:
void findCust(Customer customers[], int loc)
{
string name;
const int t = 100;
cout << "\nEnter the name of the customer you would like to look up: ";
getline(cin, name);
cout << endl;
for (int i = 0; i <= loc; i++) {
}
}
This is how the Customer struct is:
struct Customer {
string firstname;
string lastname;
Address home;
Address business;
};
Here's my main function:
int main() {
title("Customer Contact Menu");
int choice = 0;
int loc = 0;
const int SIZE = 100;
Customer contacts[SIZE];
while (choice < 5) {
choice = displayMenu();
switch (choice) {
case 1:
contacts[loc] = getCustomer();
loc++;
break;
case 2:
for (int x = 0; x < loc; x++) {
showCustomer(contacts[x]);
}
break;
case 3:
findCust(contacts,loc);
break;
case 4:
endProg();
}
}
}
I want to know how exactly to read information stored in the customer array, and compare it to the user input. I tried using a customer.compare command, I've tried a few things as well, I tried a linear search etc. But the problem with this is user input can't be compared to a structure. That's the part I'm stuck on.
If I understood your question correctly you want to read and find a customer, and then print their information. In order to do this I would structure the function like so:
void findCust(Customer customers[], int array_size)
{
string first_name, last_name;
cout << "\nEnter the name of the customer you would like to look up: ";
cin >> first_name >> last_name;
for (int i = 0; i < array_size; i++) {
}
}
Inside the for loop you can run a linear search and just iterate over all the customers and compare them. i.e. Go through the array and for each customers[i].firstname and customers[i].lastname check if they match the first_name and last_name variables.
If they do then call print(customers[i]) which is the function that will print out the given customer. You can have the function's definition be similar to void print(Customer customer) and this can contain all the printing to the stream.
Hopefully that helps you get started.
Related
Here I have an array of Agents, and I want to initialize an array of Players. An agent has just his name. The user must input the player name, jersey number, and player's agent. In this case, I wanted multiple players to be able to have the same agent, so I used a pointer.
// Default constructor = Agent(std::string = "")
Agent agents[2] = {"Larry", "Joe"};
// Default constructor = Player(std::string = "", int = 0, Agent* = 0)
Player players[3];
initializePlayers(players, 3);
void initializePlayers(Player players[], int playerSize)
{
string playerName, agentName;
int playerNum;
Agent *myAgent;
for(int i = 0; i < playerSize; i++)
{
cout << "Please enter the player's name: ";
getline(cin, playerName);
cout << "Please enter the player's number: ";
cin >> playerNum;
cout << "Please enter the player's agent: ";
getline(cin, agentName);
cin.ignore(1000, '\n');
// If the agent's name matches one of the names in agents array
// assign that agent to this player
Player tempPlayer(playerName, playerNum, myAgent);
players[i] = tempPlayer;
}
}
Inside my comments, I need to assign myAgent. For example, if the user enters "Larry" for the first player, Larry should be his agent. If the user enters "Joe" for the next two players, they should both have Joe as their agents. How do I accomplish this? Even an idea to get me started would help. Thank you.
First you should better use a std::array like that:
// Default constructor = Agent(std::string = "")
std::array<Agent, 2> agents = { Agent("Larry"), Agent("Joe") };
Then you can search for the agent like this:
myAgent = nullptr;
for (unsigned i = 0; i < agents.size(); ++i)
{
if (agentName == agents.getName())
myAgent = &agents[i];
}
I've started programming using C++ few weeks back.
I'm working on an application store user input data into an array list. When entering user data the application must be able to check whether the user already exists in the array list.
The program is unable to store the user input or able to check whether the user already exists in the array list..
int linearSearch(int array[], int size, int searchValue)
{
for (int i = 0; i < size; i++)
{
if (searchValue == array[i])
{
return i;
break;
}
}
return -1;
}
void customerReg(){
const int Capacity = 99;
int cnic[Capacity];
int customerNic;
int search = 0;
cout << "Enter Customer NIC: \n";
cin >> cnic[Capacity];
search = linearSearch(cnic, Capacity, customerNic);
if (search != -1){
cout << "Customer is already registered!\n";
}
else {
string customerName;
cout << "Enter Customer Name: \n";
cin >> customerName;
}
What about:
...
cout << "Enter Customer NIC: \n";
cin >> customerNic; // <=== instead of: cnic[Capacity];
Other remarks:
the break is not necessary: the return will already interupt the search loop
cnic[Capacity] is out of range, so puting a value in it might cause some troubles
cnic[] is not initialised
It is not clear how you fill cnic[], which is by the way local to the function and be lost as soon as you return from it.
Depending how you initalize/fill cnic, it could make sense to keep track of the number of customers that are registered in the table.
Edit:
I assume that you can't use vectors or maps for your exercise, and that you're right at the beginning of your learning.
So I suppose that customerReg() is the first function that you are working on, and that others will follow (display, delete, modifiy...). If this is the case, you have to keep your customer data outside the functions:
const int Capacity = 99;
int cnic[Capacity] {};
int customer_count=0; // counter to the last customer inserted
Then in customerReg() you should call your search function using the number of customers instead of the maximal Capacity:
search = linearSearch(cnic, customer_count, customerNic);
Later, in the else branch you have to insert the new id into the array:
else {
if (customer_count==Capacity) {
cout << "Oops ! Reached max capacity"<<endl;
else {
string customerName;
cout << "Enter Customer Name: \n";
cin >> customerName;
...
cnic[customer_count] = customerNic; // here you store the id
... // store (I don't know where) the other customer elements you've asked for
customer_count++; // increment the number of users that are stored.
}
}
I'm having quite the issue trying to figure out why these code segments are printing the error message even when I have done cout statements within the block that should return true / not print that error message. Any ideas? I'm new here so please let me know if this isn't allowed. Thanks!
Use of function:
case 'a':
{
// Format: a ID credits GPA
// Adds a student with the given student ID (ID), number of
// credits (credits), and overall GPA (GPA) to the database.
// If the student is already in the database, an error
// message should be printed indicating this.
int credits = 0;
double gpa = 0;
cin >> studentID;
cin >> credits;
cin >> gpa;
// Adds the student and checks to see if the student was actually added
// or if there was an existing student with the specified ID
bool added = addStudent(studentID, credits, gpa);
if(added == false);
{
cout << "Student already exists in database, nothing changed." << endl;
// Still prints this when executed with valid
}
break;
}
Function for adding student to array:
bool addStudent (int id, int numCredits, double gpa) {
// Check to see if student exists
if (nextEntry != 0)
{
for (int x = 0; x < 7000; x++) {
Student tmp = studentRecords[x];
if (tmp.studentId == id)
{
return false;
cout << "hey" << endl;
}
}
}
// If student does not exist, add to records database
if (nextEntry != 7000)
{
studentRecords[nextEntry].studentId = id;
studentRecords[nextEntry].numCredits = numCredits;
studentRecords[nextEntry].gpa = gpa;
nextEntry++;
return true;
// confirmed I can get here
}
return false;
}
You have an extra ; after your if (added==false) statement. This will terminate the if statement and the code after will run regardless of the check.
I have written a function in a program for entering a unique number but its not working. Something is wrong with the for loop.
I need to validate that employee id is unique.
I have made a structure named employee and "emp.id" is employee id. When the user inputs an id, it should not match previous Id's which user might have entered before. This is just a function of the main program, which validates that employee id is unique.
void uniquieid()
{
int check,i;
string code;
string tempemp1;
cout<< "enter id";
cin>> code;
while(!(num-1))
{
for(i=0;i<=num-1;i++)
{
if(emp[i].id.compare(code)==0)//comparing
{
check =1;
cout<<"enter id again";
break;
}
if(check=0) //csaasc
{
emp[i].id=code;
}
}
}
getch();
}
If the order that the ids are entered doesn't matter, I would do something like (note: untested):
using EmpIds = std::set<std::string>;
void addUniqueId(EmpIds& ids)
{
std::pair<EmpIds::iterator, bool> inserted;
const char* again = "";
do {
std::cout << "enter id" << again;
again = " again";
std::string id;
if (!(std::cin >> id))
throw std::runtime_error("No more ids!");
inserted = ids.insert(id);
} while (!inserted.second);
}
There are so many things wrong with the code, but maybe it should look more like this:
void uniqueid() {
int check=1;
string code;
string tempemp1;
cout<< "enter id";
while(check) {
cin >> code;
check = 0;
for (int i = 0; i < num; ++i) {
if (emp[i].id.compare(code)==0) {
check = 1;
cout << "enter id again";
break;
}
}
if (check==0) {
/* emp[i].id=code; */
}
}
getch();
}
Note how int check=1; starts at 1 to mean that the code needs re-entering.
So while(check) means that while the code is not unique keep going.
The for loop does the compare as before, but note the idiomatic form.
The other if (check==0) is outside the for loop and this means that no duplicates were detected so code can be used. However, I'm not sure which employee the code should apply to so I've just commented out the code.
Can you post the employee structure?
Because from this, everything looks OK, but your if function refers to emp.
So something in your structure is causing the problem.
Without your structure, anyone answering probably won't be able to find the problem.
Right now, all i can advise you to do is store employee ids in a vector and iterate through it using a for loop.
You could do
void uniqueid() {
std::vector<std::string> empIds;
std::string code;
CODE TO STORE IDs INTO VECTOR HERE;
int vectorLength = empIds.size();
std::cout << "enter id";
std::cin >> code;
for (int i = 0; i < vectorLength; i++) {
if (empIds[i] == code) {
std::cout << "enter id again";
std::cin >> code;
} else {
empIds.push_back(code);
}
}
}
For a start, something like the below should work.
map <string, bool> seen;
bool isUniqueId(string id)
{
return seen[id];
}
void addId(string id)
{
seen[id] = true;
}
From main(), whenever user inputs a string id, use isUniqueId(id) to ensure its unique, and if its unique, call addId(id).
Edit : (upon request from the OP)
Your transformed code may look like below after using map.
// Global map, defaults to false
map <string, bool> seen; // seen map to store if an id is seen already or not.
void uniqueId()
{
bool good = true; // set up a good flag to check if id is good or not.
int numEmployees = 0; // Count to store number of employees with unique ids so far
string id;
cout<< "enter id\n";
cin>> id;
while(good)
{
good = false; // Assume this is unique!
if(seen[id]) // Check if we already saw this id before
{
good = true; // Alas! We already have seen this id
cout<<"enter id again\n";
continue; // If id already exists, ask for another id setting good = true;
// Note that the above continue is NOT required as loop will run again (good = true).
// Just for clarity sake.
}
else
{
// Voila, we have a new employee with unique id.
seen[id] = true; // Unique, mark as seen now
emp[numEmployees].id=code; // Note numEmployees here
numEmployees++; // Increment the count
}
}
getch();
}
At the end of while loop, you would have successfully gotten a unique id from user, otherwise it will keep asking the user for new id.
I have been trying to do this all day but something is just not OK. I'm trying to make a system that reads students from text file and creates three new files. The three files are: Normal, Failed, New. Everything depends of the student's number. If it has 'D' in the beginning the student should go to the file with failed students. If there is 'I' in front of the number the student should go to the file named "New". If there is nothing in the beginning the student should go to the "Normal" file.
The problem is that if the students data is inserted manually to the file by the user everything is ok. But I have a function that reads student's data and inserts it in the main file. If there is nothing in front of the number everything is ok when I try to read all students from the file. But if there is a letter, the data is not being written in the proper(any) file.
Here is example: Let's have a ready file with data in it:
989123 John Brown //Should go to the "Normal" file
I112233 Steve Round //Should go to the "New" file
D101010 Wayne Bruce //Should go to the "Failed" file
And if I try to read the data and insert it into the proper files everything is ok.
But let's say that the user has choosed the "Add student" option from the applications menu. And the user inserts a new record. For example:
D818181 Some Guy //Should go to the "Failed" file
but it doesn't go there. I don't know what's the reason. If the user has entered a student number without any letter everything is OK but if there is a letter it is not shown in the file. I hope you got my mind. Here is the code. Every help will be appreciated.
#include<iostream>
#include<fstream>
#include<string>
using namespace std;
struct Student
{
int number;
string name;
string secondName;
};
Student Failed[50], New[50], Normal[50];
int o = -1;
int v = -1;
int n = -1;
int MakeInt(string number, bool ignoreFirst)
{
int num;
if(ignoreFirst)
{
number[0] = '0';
num = atoi(number.c_str());
}
else
{
num = atoi(number.c_str());
}
return num;
}
void zapis_student(string number, string name, string secondName)
{
if(number[0] == 'D')
{
int num = MakeInt(number, true);
Student temp;
temp.number = num;
temp.name= name;
temp.secondName = secondName;
o++;
Failed[o] = temp;
}
else if(number[0] == 'I')
{
int num = MakeInt(number, true);
Student temp;
temp.number = num;
temp.name = name;
temp.secondName = secondName;
v++;
New[v] = temp;
}
else
{
int num = MakeInt(number, false);
Student temp;
temp.number = num;
temp.name = name;
temp.secondName = secondName;
n++;
Normal[n] = temp;
}
}
void ReadFile()
{
ifstream fp("studenti.txt", ios::in);
if(fp.fail())
{
cout<<"Error!"<<endl;
}
while(fp.good())
{
string number, name, secondName;
fp >> number >> name >> secondName;
zapis_student(number, name, secondName);
}
fp.close();
}
void sortir(Student a[], int br)
{
for(int i = 0; i < br; i++)
{
for(int j = 0; j < br-1; j++)
{
if(a[j].number>a[j+1].number)
{
Student buf = a[j];
a[j] = a[j+1];
a[j+1] = buf;
}
}
}
}
void MakeFile(Student a[], int br, char ime_fail[])
{
ofstream fp(ime_fail);
for(int i = 0; i < br; i++)
{
fp << a[i].number << " " << a[i].name << " " << a[i].secondName << endl;
}
fp.close();
}
void AddStudent()
{
fstream fp("studenti.txt", ios::app);
string number, firstName, secondName;
cin >> number >> firstName >> secondName;
fp << number << " " << firstName << " " << secondName << endl;
fp.close();
}
void SortStudents()
{
sortir(Failed, o);
sortir(New, v);
sortir(Normal, n);
}
int main ()
{ int ans;
do
{ cout<<"******************************Menu***********************************"<<endl;
cout<<"* *"<<endl;
cout<<"* 1. Add student. *"<<endl;
cout<<"* 2. Read file. *"<<endl;
cout<<"* 3. Sort students. *"<<endl;
cout<<"* 4. Make Normal file. *"<<endl;
cout<<"* 5. Make Failed file. *"<<endl;
cout<<"* 6. Make New file. *"<<endl;
cout<<"* 7. Exit! *"<<endl;
cout<<"* *"<<endl;
cout<<"*********************************************************************"<<endl;
cout<<endl<<"Choice: "<<endl;
do
{cin>>ans;} while((ans<1)||(ans>7));
switch(ans)
{ case 1:AddStudent();break;
case 2:ReadFile();break;
case 3:SortStudents();break;
case 4:MakeFile(Normal, n, "Normal.txt");cout<<"Suzdaden e fail NovaGrupa.txt!\n";break;
case 5:MakeFile(Failed, o, "Failed.txt");cout<<"Suzdaden e fail Izklucheni.txt!\n";break;
case 6:MakeFile(New, v, "New.txt");cout<<"Suzdaden e fail Vlizashti.txt!\n";break;
case 7:exit(1);
}
}
while(ans!=7);
}
You have just one single student per type; since you start from -1, you finish the reading with 0, which is the right index for the first element but the wrong count of elements! To fix this, I simply suggest you to start with 0, use the index and then increment. E.g.
int o = 0;
...
Failed[o] = temp;
o++;
(swapped the lines), so that o keeps the count of how many student of that kind you've read so far.
Note: you also need to handle properly the end of file and cope with the case when there's nothing that can be converted to an integer by atoi: you try anyway (and you don't have a way to notice it), and the "normal" count can be one unit greater (after the fix; before the fix, it's the correct count!)
Other suggestions
Do not use atoi (for which you should include cstdlib, and you don't)… do not ignore compiler warnings
Last argument of MakeFile should be const char *
Use better names for variable: o, v, n are poorly named.