0

I'm working on a c++ contact management system.As a feature of that system i want to search a contact name and then show the profile of that contact.I have 20 contacts in a file in the following format.

Name    Nick name   Phone number Carrier        Address
Yashodhara  Yash    711256677   Mobitel No. 29,Bollatha,Ganemulla
Madushani   Madu    711345678   Mobitel No. 12, Gampaha

I have already written a code to search a contact by its name.But i want to display the respective nick name ,phone number carrier and address along with that searched name.Below i've shown the code I wrote

ifstream fin;
    fin.open("Contact.csv");
    if (fin.fail())
    {
        cout << "Input file opening failed.\n";
        exit(1);
    }
    string search;
    cout << "Please enter the name you want to search : ";
    cin >> search;
    bool isFound = 0;
    while (!fin.eof())
    {
        string temp = "";
        getline(fin, temp);
        for (int i = 0; i < search.size(); i++)
        {
            if (temp[i] == search[i])
                isFound = 1;
            else
            {
                isFound = 0;
                break;
            }
        }

Also I have a vector of structure.I used that vector to read the file in to.

typedef struct contacts 
{
    string name;
    string nickName;
    string phoneNumber;
    string carrier;
    string address;

} contactDetails;

vector <contactDetails> proContactFile;

Is there any way to do this?

  • If `name` always comes first, fill the struct after you found the `name`. – Louis Go Aug 31 '20 at 06:52
  • What's the exact format of the file? It looks like half of it is space separated and half is comma separated. – Ted Lyngmo Aug 31 '20 at 07:02
  • Sidenote: Don't `typedef struct` for C++ classes. Just do `struct contactDetails { ... };`. Classes are automatically `typedef`ined. – Ted Lyngmo Aug 31 '20 at 07:03
  • Note: Please read [Why is `iostream::eof` inside a loop condition (i.e. `while (!stream.eof())`) considered wrong?](https://stackoverflow.com/questions/5605125/why-is-iostreameof-inside-a-loop-condition-i-e-while-stream-eof-cons) – Ted Lyngmo Aug 31 '20 at 07:08
  • @LouisGo Sorry I didn't get that mate –  Aug 31 '20 at 07:24
  • @TedLyngmo You mean the file format?.It is ".csv" –  Aug 31 '20 at 07:25
  • @TedLyngmo Noted –  Aug 31 '20 at 07:25
  • How do you fill the struct? You may just check the filled struct rather than checking raw name. – Louis Go Aug 31 '20 at 07:29
  • @LouisGo Oh yeah mate.I was thinking about it.I tried few times to implement that.But i couldn't do it.Could you please show me an example? –  Aug 31 '20 at 07:37
  • 2
    @SeektheFreak2 If you have all contracts in your vector, do you really need to search the file? – Ted Lyngmo Aug 31 '20 at 07:52
  • @TedLyngmo Yeah mate.Thats why –  Aug 31 '20 at 08:24
  • @SeektheFreak2 Sorry, I didn't quite understand why you need to search the file when you have everything in the vector? I made an answer demonstrating what I meant. – Ted Lyngmo Aug 31 '20 at 08:41

1 Answers1

0

I suggest that you put vector <contactDetails> proContactFile; inside a class and that you add member functions for searching inside the vector to that class.

I'm assuming that you already have functions for reading the file and putting it in your vector <contactDetails> proContactFile; in place, but since you didn't show them, I've added examples for that here too.

C++14 example:

#include <algorithm>
#include <fstream>
#include <iostream>
#include <iterator>
#include <string>
#include <vector>

struct contactDetails {
    std::string name;
    std::string nickName;
    std::string phoneNumber;
    std::string carrier;
    std::string address;
};

// read one contactDetails from a stream
std::istream& operator>>(std::istream& is, contactDetails& d) {
    char sep = ','; // comma separated
    std::getline(is, d.name, sep);
    std::getline(is, d.nickName, sep);
    std::getline(is, d.phoneNumber, sep);
    std::getline(is, d.carrier, sep);
    std::getline(is, d.address); // newline
    return is;
}

// write one contactDetails to a stream
std::ostream& operator<<(std::ostream& os, const contactDetails& d) {
    char sep = ','; // comma separated
    os << d.name << sep << d.nickName << sep << d.phoneNumber << sep << d.carrier
       << sep << d.address << '\n';
    return os;
}

// A class to keep the  vector<contactDetails> proContactFile
// with some added support functions
struct Contacts {

    // a member function to read the complete file and put it in the vector.
    bool read_file() {
        std::ifstream fin(filename);
        if(fin) {
            proContactFile.clear();
            std::copy(std::istream_iterator<contactDetails>(fin),
                      std::istream_iterator<contactDetails>{},
                      std::back_inserter(proContactFile));
            return true;
        }
        return false;
    }

    // a member function to write the complete vector out to a file
    bool write_file() const {
        std::ofstream fout(filename);
        if(fout) {
            std::copy(proContactFile.begin(), proContactFile.end(),
                      std::ostream_iterator<contactDetails>(fout));
            return true;
        }
        return false;
    }

    // add proxy functions to the vector that might come in handy, like size()
    auto size() const { return proContactFile.size(); }

    // ... and iterator access to the vector
    auto cbegin() const { return proContactFile.cbegin(); }
    auto cend() const { return proContactFile.cend(); }
    auto begin() const { return cbegin(); }
    auto end() const { return cbegin(); }
    auto begin() { return proContactFile.begin(); }
    auto end() { return proContactFile.end(); }

    // add a contactDetails to the vector
    template< class... Args >
    decltype(auto) emplace_back( Args&&... args ) {
        return proContactFile.emplace_back(std::forward<Args>(args)...);
    }

    // erase one contactDetails using an iterator
    template<typename It>
    auto erase(It it) { return proContactFile.erase(it); }

    // find functions
    auto find_name(const std::string& name) {
        return std::find_if(begin(), end(), [&name](const contactDetails& d) {
            return name == d.name;
        });
    }
    auto find_name(const std::string& name) const {
        return std::find_if(cbegin(), cend(), [&name](const contactDetails& d) {
            return name == d.name;
        });
    }

private:
    const char* const filename = "Contact.csv";
    std::vector<contactDetails> proContactFile;
};

Example usage:

int main() {
    Contacts contracts;
    contracts.read_file();

    auto it = contracts.find_name("Yashodhara");

    if(it != contracts.end()) {
        std::cout << "FOUND: " << *it;
    }

    // you can then make changes to the vector and save it
    // contracts.write_file();
}

Output:

FOUND: Yashodhara,Yash,711256677,Mobitel No. 29,Bollatha,Ganemulla
Ted Lyngmo
  • 37,764
  • 5
  • 23
  • 50