0

I have some table of data in a '.csv' file.I want to push those data from that file to a vector.I tried push_back.But it hasn't worked for me.I'm actually a beginner to c++.Could someone help me to sort this out?

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

vector <contacts> proContactFile;

Here is the part I read values from the file(Below)

void readContactDetails() {
    ifstream ContactFile;
    ContactFile.open("Contact.csv");
    string readString;
    if (ContactFile) {

        while (!(ContactFile.eof())) {
            getline(ContactFile, readString); // Read the column headers
            for (int i = 0; i <= 10; i++) {
                getline(ContactFile, limit[i].name, ','); // ',' is the separator
                getline(ContactFile, limit[i].nickName, ',');
                getline(ContactFile, limit[i].phoneNumber, ',');
                getline(ContactFile, limit[i].carrier, ',');
                getline(ContactFile, limit[i].address); // Read until the end of the line

            }
            proContactFile.push_back(ContactFile);
        }
    }
    else {
        cout << "Error"<< endl;//Show an error message if the file isn't opened
    }
}

It always shows the error message ->

no instance of overloaded function "std::vector<_Ty, _Alloc>::push_back [with _Ty=contacts, _Alloc=std::allocator<contacts>]" matches the argument list 

Could someone tell me whats wrong with this?

  • Your problem is `ifstream` objects can't be copied. Why are you trying to put the file stream in the vector? – drescherjm Aug 15 '20 at 14:23
  • @drescherjm Oh is that so?Then is there any alternative way to do that? – SeektheFreak Aug 15 '20 at 14:25
  • 2
    Your `vector` is a container for type `contacts`, but you are `pushing` `ifstream`. – ghost Aug 15 '20 at 14:25
  • 1
    You have a `vector `, so everything you add/push_back has to be of type `contacts`, but you are trying to add `ContactFile` which is a `ifstream`, *not* a `contacts`. – Jesper Juhl Aug 15 '20 at 14:26
  • The alternative is to put `contacts` objects into the vector. – drescherjm Aug 15 '20 at 14:26
  • 1
    What type is `limit` ? – drescherjm Aug 15 '20 at 14:26
  • 1
    @drescherjm After the vector I have put some thing like below to set a limit. ........ const int LIMIT = 10; contacts limit[LIMIT]; – SeektheFreak Aug 15 '20 at 14:30
  • 1
    `const int LIMIT = 10; contacts limit[LIMIT];` Your code is trying to read 11 items into this array of size 10. And if you have this limit array then you don't need the `proContactFile` vector because they would serve the same purpose. – drescherjm Aug 15 '20 at 14:31
  • 1
    @drescherjm Yeah i know it.i want a solution for that as well.The thing is I want add more fields to this vector and delete the existing fields too.Therefore i need this vector..But I also not sure with that [limit]..Could you give me a solution please – SeektheFreak Aug 15 '20 at 14:37

1 Answers1

1

You've defined a vector of contacts. The only thing you can push back into it is an instance of contacts. Normally your code should look like:

vector <contacts> proContactFile;       // define a vector
contacts new_contact;                   // define an instance of `contacts` struct
new_contact.name = "name";              // put some data
...
proContactFile.push_back(new_contact);  // push back that instance into the vector

There is another approach with emplace_back:

vector <contacts> proContactFile;               // define a vector
auto &contact = proContactFile.emplace_back();  // create an instance in-place and get a ref
new_contact.name = "name";                      // work with this instance through reference

Alternatively you can provide data for constructor:

auto &contact = proContactFile.emplace_back("name", "nickname", ...);

Guess you need something like this:

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

using namespace std;

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

vector <contacts> proContactFile;

void readContactDetails() {
    ifstream ContactFile;
    ContactFile.open("Contact.csv");
    string readString;
    if (ContactFile) {

        if (!(ContactFile.eof())) {
            getline(ContactFile, readString); // Read the column headers
            // reserve place in the vector, since we know how much entries we are going to add
            proContactFile.reserve(10);

            // do not know what `10` is!!!
            for (int i = 0; i < 10; i++) {
                // create a new element in the vector and get reference to it
                auto &contact = proContactFile.emplace_back();  

                // read data into the members of the struct
                getline(ContactFile, contact.name, ','); // ',' is the separator
                getline(ContactFile, contact.nickName, ',');
                getline(ContactFile, contact.phoneNumber, ',');
                getline(ContactFile, contact.carrier, ',');
                getline(ContactFile, contact.address); // Read until the end of the line
            }
        }
    }
    else {
        cout << "Error"<< endl;//Show an error message if the file isn't opened
    }
}

Disclaimer: the code demonstrates the usage of std::vector! I left the logic of file reading the same as in the question. In production ready-code one should definitely add more checks!

Vasilij
  • 1,861
  • 1
  • 5
  • 9
  • 1
    The `while (!(ContactFile.eof())) {` probably should be replaced with an if () unless the file has some heading every 11th row – drescherjm Aug 15 '20 at 15:30
  • 1
    Okay It still gives an error.It says "cannot deduce auto type".But I got the whole idea behind your answer.I think now I can figured it out. :D – SeektheFreak Aug 15 '20 at 15:30
  • 1
    @drescherjm I tried it with an if().But it gave me an error.Thats why I kept while(). – SeektheFreak Aug 15 '20 at 15:31
  • It's important to begin to learn how to read and understand error messages. The compiler may be cryptic at times but in many cases it will tell you what the problem is. – drescherjm Aug 15 '20 at 15:33
  • 2
    @drescherjm, noted, thanks. It seems more correct, though I didn't really checked that part. Should add a disclaimer. – Vasilij Aug 15 '20 at 15:33
  • @SeektheFreak, what compiler are you using? If it is old, the just replace `auto &contact` with `contacts &contact`. But emplace_back() is available since C++11. Then just use push_back, if your compiler doesn'r support it. – Vasilij Aug 15 '20 at 15:37
  • @Vasilij Okay i'll try it.Hey but i'm using visual studio 2019 . – SeektheFreak Aug 15 '20 at 15:39
  • 1
    @SeektheFreak, shouldn't be the compiler then. The problem is somewhere else then. You can play with the code here: https://godbolt.org/z/K91vhK – Vasilij Aug 15 '20 at 15:44
  • @Vasilij Okay mate.Thnk u very much – SeektheFreak Aug 15 '20 at 15:55
  • I think you need c++17 enabled for that to work. I believe c++14 is the default. Related: [https://learn.microsoft.com/en-us/cpp/build/reference/std-specify-language-standard-version?view=vs-2019](https://learn.microsoft.com/en-us/cpp/build/reference/std-specify-language-standard-version?view=vs-2019) – drescherjm Aug 15 '20 at 16:15