Reputation: 27
My task is to read this data from a file into a vector:
21000 Landhau Nolte brown
19000 Modern_fit Hoeffner magnolie
14700 Pure_Style Wellmann black
This is my attempt, but push back isn't working. I already looked at some examples here at Stack Overflow, but somehow it's not working.
functions.h
:
#pragma once
#include <iostream>
#include <string>
#include <vector>
#include <fstream>
using namespace std;
struct Kitchen {
double price;
string name;
string manufacturer;
string color;
};
main.cpp
:
#include "functions.h"
int main(){
vector<Kitchen> Kitchens;
fstream myFile;
myFile.open("kitchen.txt", ios::in);
if (myFile.is_open()) {
while (!myFile.eof()) {
double price;
string name;
string manufacturer;
string color;
myFile >> price >> name >> manufacturer >> color;
Kitchens.push_back(price, name, manufacturer, color);
}
myFile.close();
}
else cout << "not opened." << endl;
system("PAUSE");
return EXIT_SUCCESS;
}
What am I doing wrong?
Upvotes: 1
Views: 84
Reputation: 30709
Let's do this properly.
Starting with the header, don't include more than needed for the definitions in that header, and don't import all identifiers from std
into the global namespace.
#include <string>
struct Kitchen {
double price;
std::string name;
std::string manufacturer;
std::string color;
Kitchen(double price, std::string name,
std::string manufacturer, std::string color)
: price{price}, name{name}, manufacturer{manufacturer}, color{color}
{}
};
I've added a simple constructor, as we'll need that for emplace_back
later.
Now implement the main()
. For a reproducible example, it's better to read from a string stream than to have to mess about with files:
#include <vector>
#include <sstream>
#include <iostream>
int main()
{
std::vector<Kitchen> kitchens;
std::istringstream file("21000 Landhau Nolte brown\n"
"19000 Modern_fit Hoeffner magnolie\n"
"14700 Pure_Style Wellmann black\n");
{
double price;
std::string name;
std::string manufacturer;
std::string color;
while (file >> price >> name >> manufacturer >> color) {
kitchens.emplace_back(price, name, manufacturer, color);
}
}
std::clog << "Read " << kitchens.size() << " kitchens from input\n";
}
Note here that !eof()
doesn't guarantee that a read will succeed. Instead, we attempt the read, and then test whether the input stream is in a failure state. After the loop, we could (if we wanted) actually check that we reached end of file, rather than some failure condition - I've omitted that for this simple program.
Upvotes: 1
Reputation: 1921
structure is an aggregate type but for pushing struct object into vector of struct, you have to create one even though it can be temporary :
#include <iostream>
#include <vector>
using namespace std;
struct Kitchen {
double price;
string name;
string manufacturer;
string color;
};
int main() {
std::vector<Kitchen> kt;
kt.push_back(Kitchen{21000,"Landhau","Nolte","brown"});
return 0;
}
Also with minor modification and having a parameterized constructor in your Kitchen struct you can avoid internal copying/moving operation of push_back and directly use emplace_back.
#include <iostream>
#include <fstream>
#include <vector>
using namespace std;
struct Kitchen {
double price;
string name;
string manufacturer;
string color;
Kitchen(double p,
const string& n,
const string &m,
const string &c):price(p),name(n),manufacturer(m),color(c) {}
};
int main(){
vector<Kitchen> Kitchens;
fstream myFile;
myFile.open("kitchen.txt", ios::in);
if (myFile.is_open()) {
while (!myFile.eof()) {
double price;
string name;
string manufacturer;
string color;
myFile >> price >> name >> manufacturer >> color;
Kitchens.emplace_back(price, name, manufacturer, color);
}
myFile.close();
}
else cout << "not opened." << endl;
system("PAUSE");
return EXIT_SUCCESS;
}
Upvotes: 2
Reputation: 33932
push_back
takes a Kitchen
. The code is providing pieces of a Kitchen
. Give emplace_back
a try or instantiate a temporary Kitchen
to pass into push_back
.
Upvotes: 1
Reputation: 10756
What you're doing wrong is trying to pass 4 random variables to a push_back
that actually only takes one, and that one is of the value type of the vector.
Kitchen k;
myFile >> k.price >> k.name >> k.manufacturer >> k.color;
Kitchens.push_back(k);
Upvotes: 1