Delete entries in Phone database



    1. Please edit your posts and fix code formatting.
    2. Split your code into several functions which perform one specific task.
    3. You can use std::regex and std::regex_search to find partial matches
    4. Use std::vector::erase() instead of rearranging elements yourself.
    5. Get rid of index. std::vector offers a size() function which returns the number of elements the vector contains
    6. Take advantage of iterators. Get rid of index variables at all.


  • @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 an Address 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());



  • @codinglover2022

    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 is addresses: plural because it is a vector. And address because the objects are of type Address.



  • 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.


Anmelden zum Antworten