Delete entries in Phone database
-
@DocShoe Ok here is the code. How can I use regex for partial match?
"```"
void ContactDelete(vector<Address>& list)
{
int entrynum, tmp = 0, index = 0;
charresponse;
system("cls");
cout << "\nProvide details of the Entry Number to Delete: ";
cin >> entrynum;tmp = entrynum - 1;
if (entrynum > index)
{
cout << "There are only " << index << " entries in the book";
ContactDelete(list);
}
else
{
cin.clear();
cin.ignore();
cout << "\n[" << tmp + 1 << "]";
cout << setw(15) << list[tmp].fname;
cout << setw(15) << list[tmp].lname;
cout << setw(30) << list[tmp].addr;
cout << setw(15) << list[tmp].phone;
cout << endl << endl;
cout << "Delete Selected Entry? [Y]/[N]";
cin >> response;
if (response == 'y' || response == 'Y')
{
for (int i = tmp; i < (index - 1); i++)
{
list[i].fname = list[i + 1].fname;
list[i].lname = list[i + 1].lname;
list[i].addr = list[i + 1].addr;
list[i].phone = list[i + 1].phone;
}
--index;
ofstream fout;
fout.open("C:/Users/Delise/Documents//sample.txt");
for (int i = 0; i < index; i++)
{
fout << list[i].fname << "," << list[i].lname << "," << list[i].addr << "," << list[i].phone << ",";
}
fout.close();
cout << "\nSuccess Delete Entry!" << endl;
cout << endl << endl;
}
else if (response == 'n' || response == 'N')
cout << "Entry Deletion cancelled..." << endl;
}
cout << "Go to Main menu? [y]/[N]" << endl;
cin >> response;
if (response == 'y' || response == 'Y')
return;
else if (response == 'n' || response == 'N')
{
ContactDelete(list);
}
system("PAUSE");
}"```"
-
If you don´t put effort in formatting your code properly, why do you think I would put effort in providing a solution/hint?
-
@DocShoe Please find formatted code here.
Kindly review it."```"
void ContactDelete(vector<Address>& list)
{
int entrynum, tmp = 0, index = 0;
charresponse;
system("cls");
cout << "\nProvide details of the Entry Number to Delete: ";
cin >> entrynum;tmp = entrynum - 1; if (entrynum > index) { cout << "There are only " << index << " entries in the book"; ContactDelete(list); } else { cin.clear(); cin.ignore(); cout << "\n[" << tmp + 1 << "]"; cout << setw(15) << list[tmp].fname; cout << setw(15) << list[tmp].lname; cout << setw(30) << list[tmp].addr; cout << setw(15) << list[tmp].phone; cout << endl << endl; cout << "Delete Selected Entry? [Y]/[N]"; cin >> response; if (response == 'y' || response == 'Y') { for (int i = tmp; i < (index - 1); i++) { list[i].fname = list[i + 1].fname; list[i].lname = list[i + 1].lname; list[i].addr = list[i + 1].addr; list[i].phone = list[i + 1].phone; } --index; ofstream fout; fout.open ("C:/Users/Delise/Documents//sample.txt"); for (int i = 0; i < index; i++) { fout << list[i].fname << "," << list[i].lname << "," << list[i].addr << "," << list[i].phone << ","; } fout.close(); cout << "\nSuccess Delete Entry!" << endl; cout << endl << endl; } else if (response == 'n' || response == 'N') cout << "Entry Deletion cancelled..." << endl;
}
cout << "Go to Main menu? [y]/[N]" << endl;
cin >> response;
if (response == 'y' || response == 'Y')
return;
else if (response == 'n' || response == 'N')
{
ContactDelete(list);
}
system("PAUSE");
}"```"
-
Updated code
void ContactDelete(vector<Address>& list) { int entrynum, tmp = 0, index = 0; charresponse; system("cls"); cout << "\nProvide details of the Entry Number to Delete: "; cin >> entrynum; tmp = entrynum - 1; if (entrynum > index) { cout << "There are only " << index << " entries in the book"; ContactDelete(list); } else { cin.clear(); cin.ignore(); cout << "\n[" << tmp + 1 << "]"; cout << setw(15) << list[tmp].fname; cout << setw(15) << list[tmp].lname; cout << setw(30) << list[tmp].addr; cout << setw(15) << list[tmp].phone; cout << endl << endl; cout << "Delete Selected Entry? [Y]/[N]"; cin >> response; if (response == 'y' || response == 'Y') { for (int i = tmp; i < (index - 1); i++) { list[i].fname = list[i + 1].fname; list[i].lname = list[i + 1].lname; list[i].addr = list[i + 1].addr; list[i].phone = list[i + 1].phone; } --index; ofstream fout; fout.open ("C:/Users/Delise/Documents//sample.txt"); for (int i = 0; i < index; i++) { fout << list[i].fname << "," << list[i].lname << "," << list[i].addr << "," << list[i].phone << ","; } fout.close(); cout << "\nSuccess Delete Entry!" << endl; cout << endl << endl; } else if (response == 'n' || response == 'N') cout << "Entry Deletion cancelled..." << endl; } cout << "Go to Main menu? [y]/[N]" << endl; cin >> response; if (response == 'y' || response == 'Y') return; else if (response == 'n' || response == 'N') { ContactDelete(list); } system("PAUSE"); }
-
Your functions are doing too much. Let's look at "ContactDelete". What does it do?
a) Ask user for input
b) print anAddress
object
c) move objects from a position to previous position (in a loop)
d) write to a file
e) call itself
f) all of a) to e)The answer is f, obviously. This is way more than what a "ContactDelete" function should be doing. It should only do c). But you don't even need to implement c) yourself. See https://en.cppreference.com/w/cpp/container/vector/erase
So the most important lesson is: split your code into simple short functions which only do one thing.
As for your question about finding substrings in strings: there is string::contains from C++23, if you have an older version (likely), you can use string::find instead:
if (fullname.find(substring) != std::string::npos) { /* found */ } else { /* not found */ }
-
Are you saying you could easily remove the name using the vector::erase along with std::remove?
Something like this as below.
#include <algorithm>
//...
name.erase(std::remove(name.begin(), name.end(), delete_contact), name.end());
-
Not quite, but close enough. There´s the erase-remove idiom. The idea is to provide some kind of criterion to identify the elements you want to remove from the vector. This is usually achieved by calling std::remove_if along with a lambda:
void some_func( std::vector<address>& addresses ) { // Lambda identifying the elements to be removed auto predicate = []( address const& addr ) { // return true to remove the given addr, false otherwise }; addresses.erase( std::remove_if( addresses.begin(), addresses.end(), predicate ), addresses.end() ); } }
Edit:
The erase-remove idiom is used when you want to remove multiple elements from the vector. If you want to remove only one item you can use a similar approach that removes the first element found:void some_func( std::vector<address>& addresses ) { // Lambda identifying the elements to be removed auto predicate = []( address const& addr ) { // return true to remove the given addr, false otherwise }; auto it = std::find_if( addresses.begin(), addresses.end(), predicate ); if( it != addresses.end() ) { addresses.erase( it ), } }
-
@codinglover2022 sagte in Delete entries in Phone database:
Are you saying you could easily remove the name using the vector::erase along with std::remove?
Something like this as below.
#include <algorithm>
//...
name.erase(std::remove(name.begin(), name.end(), delete_contact), name.end());You are asking the user for the entry number to delete.
Therefore simply:
addresses.erase(addresses.begin() + i)
.
No need for erase-remove.Also: Not sure why you are now naming your vector of Address
name
. An address vector is not a name. The most generic name isaddresses
: plural because it is avector
. And address because the objects are of typeAddress
.
-
Below is the modified code , based on your inputs. Please review it.
void ContactDelete(vector<Address>& list) { int tmp = 0, index = 0; char response; auto predicate = [] (Address const& addr) { }; auto it = std::find_if(list.begin(), list.end(), predicate); if(it != list.end()) { list.erase(it), } cout << setw(15) << list[tmp].fname; cout << setw(15) << list[tmp].lname; cout << setw(30) << list[tmp].addr; cout << setw(15) << list[tmp].phone; cout << endl << endl; cout << "Delete Selected Entry? [Y]/[N]"; cin >> response; if (response == 'y' || response == 'Y') { for (int i = tmp; i < (index - 1); i++) { list[i].fname = list[i + 1].fname; list[i].lname = list[i + 1].lname; list[i].addr = list[i + 1].addr; list[i].phone = list[i + 1].phone; } ofstream fout; fout.open ("C:/Users/Delise/Documents//sample.txt"); for (int i = 0; i < index; i++) { fout << list[i].fname << "," << list[i].lname << "," << list[i].addr << "," << list[i].phone << ","; } fout.close(); cout << "\nSuccess Delete Entry!" << endl; cout << endl << endl; } else if (response == 'n' || response == 'N') cout << "Entry Deletion cancelled..." << endl; } cout << "Go to Main menu? [y]/[N]" << endl; cin >> response; if (response == 'y' || response == 'Y') return; else if (response == 'n' || response == 'N') { ContactDelete(list); } system("PAUSE"); }
-
F mark
You just copied a meaningless code snippet at the beginning of the function and did not change the rest. Even your lambda does not return a value.