Delete entries in Phone database



  • I am writing a phone app which stores user name, phone contact details, address etc in the phone book . I am trying to delete an entry, but doesn't work. Below is my code. Not sure what went wrong here in this code, as THE OUTPUT shows that "There are only 0 entries in the book", though I can see many entries while displaying the content.

    Also need to fetch names based on search string provided by the user. Right now in my code if i search for name by providing full string, only then it displays that name. I would rather need that name to be displayed based on search string. For example if the Phone DB has a name "James John" and if I type only the first or last full name, it returns the name. But if I search by string like "Jam or Jo or Ja or Jame", nothing is displayed. How to search for partial values? This string matching must not be case sensitive. how to read image file .BMP .PNG from address book field in c++ and determine size of the image file ? Please provide your inputs.

    "```cpp"
    void ContactDelete(vector<Address>& list)
    {
    int entrynum, tmp = 0, index = 0;
    char response;
    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);
    }
    /*bool is_ok = false;
    while(! is_ok)
    {
    	cout << "\nProvide the Entry Number to Delete: ";
    	cin >> entrynum;
    	if (entrynum > index)
    		cout << "There are only " << index << " entries in the address book" << endl;
    	else 
    		break;
    }
    tmp = entrynum - 1;*/
    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"); 
    

    }

    "```"



  • @codinglover2022 sagte in Delete entries in Phone database:

    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");
    Expand/Collapse
    }
    "```"

    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);
    }
    /*bool is_ok = false;
    while(! is_ok)
    {
    	cout << "\nProvide the Entry Number to Delete: ";
    	cin >> entrynum;
    	if (entrynum > index)
    		cout << "There are only " << index << " entries in the address book" << endl;
    	else 
    		break;
    }
    tmp = entrynum - 1;*/
    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"); 
    }
    
    


    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