How to alphabetize a list on C++ - c++

I have been having some trouble on my code for my final project. I have looked everwhere and I am having a hard time so I thought I would ask on here. I need to make sure that when all the names are listed in this phonebook that they will come out in alphabetical order but as of yet I am unsure how to do that. Here is the program that i currently have! Thank you!
#include <iostream>
#include <iomanip>
#include <fstream>
#include <string>
using namespace std;
struct Contact {
string name, number, notes;
};
Contact contactList[100];
int rec_num = 0;
int num_entries;
string toUpper (string S) {
for (int i= 0; i < S.length(); i++)
S[i] = toupper(S[i]);
return S;
}
void ReadFile () {
string S;
fstream input("PhoneData.txt");
while (!input.eof() && !input.fail()){
input >> contactList[rec_num].name >> contactList[rec_num].number;
getline(input, S);
contactList[rec_num].notes = S;
rec_num++;
}
cout << "Book read." << endl;
num_entries = rec_num;
input.close();
return;
}
// stores phonebook for future runs of the program
void StoreFile () {
fstream F ("PhoneData.txt");
rec_num = 0;
while (rec_num < num_entries){
F << contactList[rec_num].name << " " << contactList[rec_num].number << " " << contactList[rec_num].notes << " " << endl;
rec_num++;
}
cout << "Phonebook stored." << endl;
return;
}
// adds contact
void add_name(string name, string number, string notes){
contactList[num_entries].name = name;
contactList[num_entries].number = number;
contactList[num_entries].notes = notes;
num_entries++;
return;
}
// finds contact
void retrieve_name(string name){
for (int i = 0; i < num_entries; i++){
if (toUpper(contactList[i].name) == toUpper(name)) {
cout << "Phone Number: " << contactList[i].number << endl << "Notes: " << contactList[i].notes << endl;
return;
}
}
cout << "Name not found" << endl;
return;
}
// updates contact info
void update_name(string name){
string new_number;
string new_notes;
cout<<"New Phone Number"<<endl;
cin>> new_number;
cout<<"New Notes"<<endl;
cin>> new_notes;
for (int i = 0; i < num_entries; i++){
if (toUpper(contactList[i].name) == toUpper(name)) {
contactList[i].number = new_number;
contactList[i].notes = new_notes;
return;
}
}
}
// deletes contact
void delete_name(string name){
int INDEX=0;
for (int i = 0; i < num_entries; i++){
if (toUpper(contactList[i].name) == toUpper(name)) {
INDEX=i;
for ( int j=INDEX; j < num_entries; j++ ){
contactList[j].name = contactList[j+1].name;
contactList[j].number = contactList[j+1].number;
contactList[j].notes = contactList[j+1].notes;
}
}
}
return;
}
void listAllContacts() {
int i = 0;
while (i < num_entries) {
cout << "-- " << contactList[i].name << " " << contactList[i].number << endl << "-- " << contactList[i].notes << endl << endl;
i++;
}
}
int main(){
string name, number, notes;
string FileName;
char command;
FileName = "PhoneData.txt";
ReadFile ();
cout << "Use \"e\" for enter, \"f\" for find, \"l\" for list, \"d\" for delete, \"u\" for update, \"s\" for send message, \"q\" to quit." << endl << "Command: ";
cin >> command;
while (command != 'q'){
switch (command){
case 'e': cin >> name; cout << "Enter Number: ";
cin >> number; cout << "Enter Notes: ";
cin.ignore(); getline(cin, notes);
add_name(name, number, notes); break;
case 'f': cin >> name; retrieve_name(name); break;
case 'l':
listAllContacts(); break;
case 'u': cin>> name; update_name (name);break;
case 'd' : cin>> name; delete_name (name); break;
}
cout << "\nCommand: "; cin >> command;
}
StoreFile();
cout << "All set !";
return 0;
}

Given
Contact contactList[100];
int num_entries;
you can use std::sort to sort the list of contacts. std::sort has two forms. In the first form, you can use:
std::sort(contanctList, contactList+num_entries);
if you define operator< for Contact objects.
In the second form, you can use:
std::sort(contanctList, contactList+num_entries, myCompare);
if you define myCompare to be callable object that can compare two Contact objects.
To use the first form, change Contact to:
struct Contact {
string name, number, notes;
bool operator<(Contact const& rhs) const
{
return (this->name < rhs.name);
}
};
If you want to the comparison of names to be case insensitive, convert both names to either uppercase or lowercase and them compare them.

Related

Dealing with file io in c++

I have a program that takes input for names and outputs the last names in a string. The task I have now is to include FileIO in it. Specifically, "get user input for the filename, and then read the names from the file and form the last name string."
When I run the program, the console will show the name string from the text file. But only initially. As you keep entering names, that string disappears. Also, my user input for file name seems to be doing nothing, because I can enter anything and it still show the string of last names from the text file.
Here is what I have so far. Included all of it, just to make sure.
#include <iostream>
#include <string>
#include <vector>
#include <sstream>
#include <fstream>
using namespace std;
// function declerations
int Menu();
void getName(vector<string> &names, int &count);
void displayName(vector<string> &names, int count);
string getLastNames(vector<string> &names, int count);
int main()
{
vector<string> names;
int count = 0;
int choice = Menu();
ifstream File;
string line;
cout << "Enter file name: ";
getline(cin,line);
File.open("File.txt");
while(File.good()){
getline(File,line);
cout << line << endl;
}
File.close();
while (choice != 0)
{
// switch statement to call functions based on users input
switch (choice)
{
case 1: {
getName(names, count);
} break;
case 2: { displayName(names, count); } break;
case 3: {
cout << getLastNames(names, count) << endl;
} break;
case 0: {
return 0;
} break;
}
choice = Menu();
}
return 0;
}
// function definition for vector of strings
void getName(vector<string> &names, int &count)
{
string name;
// get input for name
cout << "Enter name: ";
getline(cin, name);
// find position of space in string
int pos = name.find(' ');
// reverse order of name
if(pos != -1) {
string first = name.substr(0, pos);
string last = name.substr(pos+1);
name = last + "," + first;
}
// add name to end of vector
names.push_back(name);
count++;
}
// give user option of what to do
int Menu() {
int choice;
cout << "1. Add a name" << endl;
cout << "2. Display names " << endl;
cout << "3. Show all Last Names" << endl;
cout << "0. Quit" << endl;
cout << "Enter a option: ";
cin >> choice;
// if outside of above choices, print 'choice not on list'
while (choice < 0 || choice > 3)
{
cout << "Choice not on list: ";
cin >> choice;
}
cin.ignore();
return choice;
}
// defining function that gets last names
string getLastNames(vector<string> &names, int count) {
stringstream ss;
for (int i = 0; i<count; i++)
{
int pos = names[i].find(',');
if (pos != -1) {
ss << "\"" << names[i].substr(0, pos) << "\", ";
} else {
ss << "\"" << names[i] << "\", ";
}
}
return ss.str();
}
// display the names
void displayName(vector<string> &names, int count)
{
if (count == 0)
{
cout << "No names to display" << endl;
return;
}
for (int i = 0; i<count; i++)
{
cout << names[i] << endl;
}
}

how to find a specific target in the array c++

The search function should get a value from the user to search for it, if the value is found, then it should print it out, and if not found it should print not found.
However, in my code every time I write the number that is in the array is gives me the false option although it is in the array stored.
`
#include <iostream>
using namespace std;
const int size = 100;
int partsmenu(int menu_option);
void readparts(char part_number[][10], double price[], char classification[], int& number_of_parts);
int search(char part_number[][10], char search_target[], int number_of_parts, double price[], char classification []);
void display_parts(char part_number[][10], double price[], char classification[], int& number_of_parts);
int main()
{
const int size = 100;
int menu_option=0, option, displaysearch;
char part_number[size][10];
double price[size];
char classification[size];
int number_of_parts = 0;
char search_target[size];
//using switch statment to make it look like a menu option
do {
switch (option = partsmenu(menu_option))
{
case 1:
readparts(part_number, price, classification, number_of_parts);
break;
case 2:
display_parts(part_number, price, classification, number_of_parts);
break;
case 3:
displaysearch = search(part_number, search_target, number_of_parts, price, classification);
break;
case 4:
break;
default:
cout << "Not valid..." << endl;
break;
}
cout << endl;
} while (option != 4);
return 0;
}
int partsmenu(int menu_option)
{
cout <<"1) Enter new part number\n2) View all part numbers\n3) Search for part\n4) Exit\n\nEnter an option: ";
cin >> menu_option;
return menu_option;
}
void readparts(char part_number[][10], double price[], char classification[], int& number_of_parts)
{
// using for loop to store part number, price, and classification in the array
int number;
cout << "Enter number of parts to add:";
cin >> number;
cout << endl;
int i;
for (i = number_of_parts; i < (number_of_parts+number); i++)
{
cout << "Enter part number: ";
cin >> part_number[i];
cout << "Enter price: ";
cin >> price[i];
cout << "Enter classificarion: ";
cin >> classification[i];
//using if statment to check for the classificarion
if (classification[i] == 'A' || classification[i] == 'B' || classification[i] == 'C')
cout << "";
else
{
cout << "Invalid case..." << endl;
cout << "Enter Valid class [A, B, C]: ";
cin >> classification[i];
cout << endl;
}
cout << endl;
}
number_of_parts = i;
}
int search(char part_number[][10], char search_target[], int number_of_parts, double price[], char classification[])
{
//searching for specific data
bool found = false;
int value;
cout << "Enter part number: ";
for (int j = 0; j < number_of_parts; j++)
{
cin >> search_target;
for (int i = 0; i < number_of_parts && found == false; i++)
{
if (part_number[i] == search_target)
found = true;
value = i;
}
}
if (found == true)
{
for (int i = 0; i < number_of_parts; i++)
{
cout << "Part ID\t\tPrice\t\tClass" << endl;
cout << " --------------------------------------------" << endl;
cout << part_number[value] << "\t\t" <<price[value]<< "\t\t" <<classification[value]<< endl;
}
}
else
{
cout << "No parts found..." << endl;
value = -1;
}
return value;
}
void display_parts(char part_number[][10], double price[], char classification[], int& number_of_parts)
{
// displaying the data
cout << "Part ID\t\tPrice\t\tClass" << endl;
cout << "--------------------------------------------" << endl;
for (int i = 0; i < number_of_parts; i++)
{
cout << part_number[i] << "\t\t" << price[i] << "\t\t" << classification[i] << endl;
}
cout << endl;
}
`
I am trying to find what is wrong with code but could not find any fault with it. Everything else works fine.
You compare C strings with strcmp not ==. Like this
if (strcmp(part_number[i], search_target) == 0)
If you use == then all you are comparing is the addresses of the strings, the addresses of two strings can be different even if the string contents are the same.
strcmp compares the actual characters in the strings, not the addresses. It returns 0 if the two strings are the same.

vector name storage list program suddenly not displaying list

Novice C++ user trying to practice program building. The point of this program is just simple name storage with vectors.
My previous program https://pastebin.com/MG1hHzgK works perfectly fine for just adding first names.
This upgraded version is supposed to have an input of First Last names then it is converted into Last, First name before being added to the list.
My problem is that after I input names, they arent added to the list. The differences between my previous program and current one are all in the function addNames and to me it looks correct when its obviously not.
Any hints or help is greatly appreciated.
#include <conio.h>
#include <stdio.h>
#include <iostream>
#include <vector>
#include <string>
using namespace std;
// Prototypes
string addNames(vector <string>& nameList);
string removeName(vector <string>& nameList);
int findName (vector <string>& nameList);
void showList(vector <string>& nameList);
void commandList(vector <string>& nameList);
void inputCall(vector <string>& nameList);
void sortList(vector <string>& nameList);
int main()
{
vector <string> nameList;
commandList(nameList);
}
void commandList(vector <string>& nameList)
{
cout << "\nPress any key to continue..." << endl;
getch();
system("cls");
cout << "Enter a Command " << endl;
cout << "<A> - Add names to the list" << endl;
cout << "<R> - Remove a name from the list" << endl;
cout << "<F> - Search for a name on the list" << endl;
cout << "<L> - Show current state of the list" << endl;
cout << "<S> - Sort the list" << endl;
cout << "<Q> - Ends the program" << endl;
inputCall(nameList);
}
// ---------------------------------------------------------------------------------------------------------------------------------------------------------------------
string addNames(vector <string>& nameList)
{
string input;
int pos = input.find(' ');
nameList.clear();
for (;true;)
{
cout << endl;
cout << "Enter a Name or 'Stop' to end name entry: " << endl;
getline(cin, input);
if (input == "Stop" || input == "stop"){
commandList(nameList);
} else if(pos != -1) {
string first = input.substr(0, pos);
string last = input.substr(pos + 1);
input = last + "," + first;
nameList.push_back(input);
commandList(nameList);
}
}
}
// ---------------------------------------------------------------------------------------------------------------------------------------------------------------------
string removeName(vector <string>& nameList)
{
string x;
cout << endl;
cout << "Enter the name to remove: " << endl;
cin >> x;
for (int i=0; i < nameList.size(); ++i) {
if (nameList[i]== x) nameList[i]="";
}
commandList(nameList);
}
// ---------------------------------------------------------------------------------------------------------------------------------------------------------------------
int findName (vector <string>& nameList)
{
string target;
int i, x=0;
int p=0;
cout << endl;
cout << "Enter a name to search for: " << endl;
cin >> target;
if (target == "Quit" || target == "quit") {exit(0);
}
for (int i=0; i < nameList.size(); i++)
{
if (nameList[i] == target)
{
cout << endl;
cout << "The entered name is listed as #" << p+1 << '.' << endl;
commandList(nameList);
return p;
}
if (nameList[i] == "") {
p--;
}
p++;
}
cout << endl;
cout << "Name not found!" << endl;
commandList(nameList);
return -1;
}
// ---------------------------------------------------------------------------------------------------------------------------------------------------------------------
void showList(vector <string>& nameList)
{
cout << endl;
cout << "The current state of the list is: " <<endl;
for (int i=0; i<nameList.size(); i++)
if(nameList[i] !="")
cout << nameList[i] << endl;
commandList(nameList);
}
void sortList(vector <string>& nameList)
{
string temp;
for (int i=0; i < nameList.size()-1; i++)
{
for (int j=0; j < (nameList.size()-i-1); j++)
{
if (nameList[j] > nameList[j+1])
{
temp = nameList[j];
nameList[j] = nameList[j+1];
nameList[j+1] = temp;
}
}
}
cout << endl;
cout << "The list has been sorted alphabetically." << endl;
commandList(nameList);
}
// ---------------------------------------------------------------------------------------------------------------------------------------------------------------------
void inputCall(vector <string>& nameList) // Function to complement the menu for switch casing
{
bool running = true;
char input;
do {
input = getch();
switch(input)
{
case 'a': addNames(nameList);break;
case 'A': addNames(nameList);break;
case 's': sortList(nameList);break;
case 'S': sortList(nameList);break;
case 'l': showList(nameList);break;
case 'L': showList(nameList);break;
case 'f': findName(nameList);break;
case 'F': findName(nameList);break;
case 'r': removeName(nameList);break;
case 'R': removeName(nameList);break;
case 'q': exit(0);break;
case 'Q': exit(0);break;
default : cout << "Unknown Command: Enter a command from the menu." << endl; continue;
}
} while (running);
}
if you insert
pos = input.find(' '); in else { } just above ( if(pos != -1) )
Your code will work

What is a deleted function, and why only my functions that I pass files into are considered deleted? [duplicate]

This question already has answers here:
Using fstream Object as a Function Parameter
(3 answers)
Closed 6 years ago.
#include <bits/stdc++.h>
using namespace std;
class contact {
private:
vector< pair<string, int> > contact_info;
public:
void add_contact(string contact_name, int contact_number) {
contact_info.push_back(make_pair(contact_name, contact_number));
sort(contact_info.begin(),contact_info.end());
}
void edit_contact(string contact_name) {
int found_at;
for (unsigned int i =0; i < contact_info.size(); i++) {
if (contact_info[i].first == contact_name) {
found_at = i;
}
}
if (contact_info[found_at +1].first == contact_name) {
int choice;
int counter = found_at;
int index = 1;
while (contact_info[counter].first == contact_name) {
cout << index << ". " << contact_info[counter].first << " " << contact_info[counter].second;
counter++;
index++;
}
cout << "Choose any please: ";
cin >> choice;
found_at = found_at - (choice - 1);
}
cout << "Enter the new number: ";
cin >> contact_info[found_at].second;
}
void show_all() {
for (unsigned int i =0; i < contact_info.size(); i++) {
cout << contact_info[i].first << " " << contact_info[i].second << endl;
}
}
void delete_contact(string contact_name) {
int found_at;
for (unsigned int i =0; i < contact_info.size(); i++) {
if (contact_info[i].first == contact_name) {
found_at = i;
}
}
if (contact_info[found_at +1].first == contact_name) {
int choice;
int counter = found_at;
int index = 1;
while (contact_info[counter].first == contact_name) {
cout << index << ". " << contact_info[counter].first << " " << contact_info[counter].second;
counter++;
index++;
}
cout << "Choose any please: ";
cin >> choice;
found_at = found_at - (choice - 1);
}
contact_info.erase(contact_info.begin()+found_at);
}
void writeFile(ofstream contact_file) {
for (unsigned int i =0; i < contact_info.size(); i++) {
contact_file << contact_info[i].first << " " << contact_info[i].second << endl;
}
}
void readFile(ifstream contact_file) {
string input;
while (!contact_file.eof()) {
contact_file >> input;
size_t pos = input.find(" ");
string name = input.substr(0,pos);
string number_str = input.substr(pos);
int number = stoi(number_str) ;
contact_info.push_back(make_pair(name,number));
}
}
};
int main()
{
int choice;
ifstream contacts_file_read;
contacts_file_read.open("contacts.txt");
ofstream contacts_file_write;
contacts_file_write.open("contacts.txt");
bool in_prog = true;
contact contacts;
string name;
int number;
while (in_prog) {
cout << "1. Add contacts" << endl
<< "2. Edit contact" << endl
<< "3. Delete contact" << endl
<< "4. Show all" << endl
<< "5. exit" << endl;
cout << "Your choice: ";
cin >> choice;
contacts.readFile(contacts_file_read);
if (choice == 1) {
cout << "Enter name & number separated by a space: ";
cin >> name >> number;
contacts.add_contact(name, number);
} else if (choice == 2) {
cout << "Enter name of contacts to be edited: ";
cin >> name;
contacts.edit_contact(name);
} else if (choice == 3) {
cout << "Enter name of contact to be deleted: ";
cin >> name;
contacts.delete_contact(name);
} else if (choice == 4) {
contacts.show_all();
} else if(choice == 5) {
contacts.writeFile(contacts_file_write);
} else {
cout << "Wrong choice" << endl;
}
}
return 0;
}
So, I was asked in my programming class to make a phone book application in C++ using only objects, so this is my attempt at it.
All functions are good, I did recompile the program after finishing each function at it gave me 0 errors, however whenever I try to call writeFile or readFile function that were previously working fine, now the compiler gave me an error of "error: use of deleted functions... "
I don't know what are deleted functions and why only functions that take file objects as an argument are treated as such.
Can anyone please help?
Thanks.
Objects of type std::ifstream are not copyable -- indeed, the object represents the unique handle of an open file, and it would be difficult to conceptualize what it would mean to copy such unique responsibility.
Indeed, this inability to copy an object is encoded by making the copy constructor deleted, which causes the error that you see when you do attempt to copy it.
Your code should pass the original ifstream, not a copy (by taking a reference parameter):
void readFile(ifstream & contact_file)
// ^^^^^^^^^^

Extra string outputs if user input is more than one word

This is my first time asking a question on here, so be gentle lol. I wrote up some code for an assignment designed to take information from a (library.txt datatbase) file, store it in arrays, then access/search those arrays by title/author then output that information for the user based on what the user enters.
The issue I am having is, whenever the user enters in a search term longer than one word, the output of "Enter Q to (Q)uit, Search (A)uthor, Search (T)itle, (S)how All: " is repeated several times before closing.
I am just looking to make this worthy of my professor lol. Please help me.
#include <iostream>
#include <fstream>
#include <string>
#include <iomanip>
using namespace std;
struct Book
{
string title;
string author;
};
int loadData(string pathname);
char switchoutput();
void showAll(int count);
int showBooksByAuthor(int count, string name);
int showBooksByTitle(int count, string title);
int FindAuthor(int count, string userinput);
int FindTitle(int count, string userinput);
void ConvertStringToLowerCase(const string orig, string& lwr); //I found this program useful to convert any given string to lowercase, regardless of user input
const int ARRAY_SIZE = 1000;
Book books[ARRAY_SIZE];
int main()
{
string pathname;
string name;
string booktitle;
int count = 0;
int counta = 0;
int countt = 0;
char input = 0;
cout << "Welcome to Jacob's Library Database." << endl;
cout << "Please enter the name of the backup file: " ;
cin >> pathname;
count = loadData(pathname);
cout << count << " records found in the database." << endl;
while (toupper(input != 'Q'))
{
input = switchoutput(); // function call for switchoutput function
switch (input)
{
case 'A':
cout << "Author's Name: ";
cin >> name;
counta = showBooksByAuthor(count, name);
cout << counta << " records found." << endl;
break;
case 'T':
cout << "Book Title: ";
cin >> booktitle;
countt = showBooksByTitle(count, booktitle);
cout << countt << " records found." << endl;
break;
case 'S':
showAll(count);
break;
case 'Q':
break;
}
}
//Pause and exit
cout << endl << "Press 'ENTER' to quit";
getchar();
getchar();
return 0;
}
int loadData(string pathname) //loading data into the array of structs
{
ifstream inFile;
inFile.open(pathname);
if (!inFile) {
cout << "Error, could not read into file. Please re-compile." << endl;
system("PAUSE");
exit(1); //if not in file, exit;
}
int i = 0;
while (!inFile.eof()) {
getline(inFile, books[i].title);
getline(inFile, books[i].author);
i++;
}
return i;
}
char switchoutput() //seperate output function to get my characteroutput constantly resetting and returning the uppercase version for my switch
{
char input;
cout << "Enter Q to (Q)uit, Search (A)uthor, Search (T)itle, (S)how All: ";
cin >> input;
return toupper(input);
}
int showBooksByAuthor(int count, string name)
{
int authorcount = 0;
authorcount = FindAuthor(count, name);
return authorcount;
}
int showBooksByTitle(int count, string title)
{
int titlecount = 0;
titlecount = FindTitle(count, title);
return titlecount;
}
void showAll(int count)
{
for (int i = 0; i < count; i++)
{
cout << books[i].title << " (" << books[i].author << ")" << endl;
}
}
int FindAuthor(int count, string userinput)
{
int authorcount = 0;
string stringlower, arraylower;
int num;
// called upon function to lowercase any of the user inputs
ConvertStringToLowerCase(userinput, stringlower);
for (int i = 0; i < count; ++i) //this function's count determines at which locations to output the author and names (an argument from books by author)
{
// called upon function to lowercase any of the stored authors'
ConvertStringToLowerCase(books[i].author, arraylower);
num = arraylower.find(stringlower); // searches string for userinput (in the lowered array) and stores its value
if (num > -1) // you can never get a -1 input value from an array, thus this loop continues until execution
{
cout << books[i].title << " (" << books[i].author << ")" << endl; //cout book title and book author
authorcount++; //count
}
}
return authorcount;
}
int FindTitle(int count, string userinput) //same as previous but for titles
{
int titlecount = 0;
string stringlower, arraylower;
int num;
ConvertStringToLowerCase(userinput, stringlower);
for (int i = 0; i < count; ++i)
{
ConvertStringToLowerCase(books[i].title, arraylower);
num = arraylower.find(stringlower);
if (num > -1)
{
cout << books[i].title << " (" << books[i].author << ")" << endl;
titlecount++; //count
}
}
return titlecount;
}
void ConvertStringToLowerCase(const string orig, string& lwr) // I found this from another classmate during tutoring, I thought to be useful.
{
lwr = orig;
for (int j = 0; j < orig.length(); ++j) //when called upon in my find functions, it takes the string and convers the string into an array of lowercase letters
{
lwr[j] = tolower(orig.at(j));
}
}