1

This question has been asked before but the other question/answers used concepts I'm not yet familiar with in C++.

I need to read data from a file into a vector of structs.

I have the following code but I'm confused about what to put in (....), that is if I have the correct logic.

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

struct Parts{
        std::string partNum;
        char partClass;
        int stock;
        float cost;
};

bool readFile(std::vector <Parts>&);
int displayMenu();

int main(){
        std::vector <Parts> pVector;

        readFile(pVector);

        if (!readFile(pVector)){
                std::cout << "Error reading file!" << std::endl;
        }
        else{
                displayMenu();
        }
        return 0;
}

bool readFile(std::vector <Parts> &pVector){
        std::ifstream inputFile("parts.txt");
        if (inputFile.fail()){
                std::cout << "Error reading file!" << std::endl;
                return false;
        }
        else{
                while (....){
                        pVector.emplace_back(....);
                }
                return true;
        }
}

Sample lines from the file:

P-42936 A 18 129.79
P-43179 A 47 35.60
P-43264 B 31 103.81
P-43367 B 5 32.39
P-43378 A 46 6.38
P-43622 A 10 155.36
5
  • cin >> xxxx is what you are looking for Commented Apr 26, 2020 at 21:50
  • If that's the case then congratulations! You're one up on Bono. He STILL hasn't found what he's looking for. Commented Apr 26, 2020 at 22:04
  • "This question has been asked before but the other question/answers used concepts I'm not yet familiar with in C++." What were they? Otherwise we'll just be prone to repeating things useless to you? Or perhaps a good opportunity to learn those concepts! Commented Apr 26, 2020 at 22:23
  • @user4581301 lol, I appreciate that reference :) Commented Apr 26, 2020 at 22:32
  • @AsteroidsWithWings The previous answer used defining the operator >> in Bruno's explanation below, but I wanted to understand the more primitive (and in this case, what my professor would be expecting from us based on what we've learned in class so far) method first Commented Apr 26, 2020 at 22:33

2 Answers 2

3

You want that :

bool readFile(std::vector <Parts> &pVector){
  std::ifstream inputFile("parts.txt");

  if (inputFile.fail()){
    std::cout << "Error reading file!" << std::endl;
    return false;
  }
  else {
    Parts part;

    while (inputFile >> part.partNum >> part.partClass >> part.stock >> part.cost)
      pVector.emplace_back(part);
    return true;
  }
}

In main you call two time the read function :

   readFile(pVector);

   if (!readFile(pVector)){

very probably the first call must be removed

It can be also interesting to define the operator >> for Parts rather than to have the code doing that in readFile

So :

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

struct Parts{
  std::string partNum;
  char partClass;
  int stock;
  float cost;
};

std::istream & operator >>(std::istream & is, Parts & part) {
  if (is >> part.partNum >> part.partClass >> part.stock)
    is >> part.cost;

  return is;
}

bool readFile(std::vector <Parts>&);
//int displayMenu();

int main(){
  std::vector <Parts> pVector;

  if (!readFile(pVector)){
    std::cout << "Error reading file!" << std::endl;
  }
  else{
    //displayMenu();
    // to check, of course operator << can be defined too
    for (auto p : pVector)
      std::cout << p.partNum << '/' << p.partClass << '/' << p.stock << '/' << p.cost << std::endl;
  }
  return 0;
}

bool readFile(std::vector <Parts> &pVector){
  std::ifstream inputFile("parts.txt");

  if (inputFile.fail()){
    std::cout << "Error reading file!" << std::endl;
    return false;
  }
  else {
    Parts part;

    while (inputFile >> part)
      pVector.emplace_back(part);
    return true;
  }
}

Compilation and execution:

pi@raspberrypi:/tmp $ g++ -Wall r.cc
pi@raspberrypi:/tmp $ cat parts.txt 
P-42936 A 18 129.79
P-43179 A 47 35.60
P-43264 B 31 103.81
P-43367 B 5 32.39
P-43378 A 46 6.38
P-43622 A 10 155.36
pi@raspberrypi:/tmp $ ./a.out
P-42936/A/18/129.79
P-43179/A/47/35.6
P-43264/B/31/103.81
P-43367/B/5/32.39
P-43378/A/46/6.38
P-43622/A/10/155.36
pi@raspberrypi:/tmp $ 
Sign up to request clarification or add additional context in comments.

Comments

3

I suggest adding overloads for operator>> and operator<<:

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

struct Part {            // I renamed it because it only holds info about one part
    std::string partNum;
    char partClass;
    int stock;
    float cost;
};

std::istream& operator>>(std::istream& is, Part& p) {
    return is >> p.partNum >> p.partClass >> p.stock >> p.cost;
}

std::ostream& operator<<(std::ostream& os, const Part& p) {
    return os << p.partNum << ' ' << p.partClass << ' ' << p.stock << ' ' << p.cost;
}

This makes extracting or printing one Part easy:

bool readFile(std::vector<Part>& pVector){
    std::ifstream inputFile("parts.txt");
    if(inputFile) {
        Part tmp;
        while(inputFile >> tmp)        // extract one Part at a time using operator>>
            pVector.emplace_back(tmp);
        return true;
    } else {
        std::cout << "Error reading file!" << std::endl;
        return false;
    }
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.