简体   繁体   中英

Reading file data to structure

For a homework assignment, I am supposed to create a program that uses structures to hold an artists' discography information; ie name, start year, end year, genre(this can be more than one) and albums with their release year(which I interpreted to mean a second structure). All this information should be read from a file.

I'm having a little bit of trouble reading data from the file into the structure variables. My main issue is that a couple of my struct variables can hold multiple strings and I am confused as to how to read them into the variables as separate values. I've tried using 2D arrays, but that doesn't seem to work, so I think that vectors might be the way to go, but that seems to be throwing up issues as well. The file is formatted as such:

artist name
artist genres;....;...
start year
end year
number of albums
album name, album year; ..., ...;

So far this is the code that I have written:

#include <fstream>
#include <iomanip>
#include <iostream>
#include <string>
#include <vector>
using namespace std;

struct Discography {
    vector<string> trackTitle;
    vector<int> trackYear;
};

struct Artist {
    string artistName;
    vector<string> genres;
    int startingYear;
    int endingYear;
    int numOfTracks;
    struct Discography disc;    
};

istream& operator>>(istream& input, Artist& artist)
{
    input >> artist.artistName;
    //input >> artist.genres;
    input >> artist.startingYear;
    input >> artist.endingYear;
    input >> artist.numOfTracks;
    //input >> artist.disc.trackTitle;
    //input >> artist.disc.trackYear;
    return input;
}


void displayFileContents();
void searchByName();
void searchByGenre();
void searchBySong();
void searchByYear();

int main()
{
    /*integer variable for menu selection*/
    int selection;
    vector<Artist> art;
                
    do
    {
        cout << "\nPlease make a selection from one of"
            << "\nthe six options below.\n";
        cout << "\n1. Display All Information\n";
        cout << "2. Search by artist name\n";
        cout << "3. Search by genre\n";
        cout << "4. Search by song title\n";
        cout << "5. Search by an active year\n";
        cout << "6. Exit Program\n";

        cout << "\nEnter your selection: ";

        /*reading user menu selection*/
        cin >> selection;

        if (selection == 1) {
            displayFileContents();
        }
        else if (selection == 2) {
            searchByName();
        }
        else if (selection == 3) {
            searchByGenre();
        }
        else if (selection == 4) {
            searchBySong();
        }
        else if (selection == 5) {
            searchByYear();
        }
        else if (selection == 6) {
            cout << "Good Bye!";
        }
        else {
            cout << "You did not enter a valid selection\n\n";
        }

    } while (selection != 6);

    return 0;
}


void displayFileContents() {
    ifstream artistFile;
    artistFile.open("My Artists.txt");
    Artist a[5];

    if (!artistFile.is_open()) {

        cout << "File could not open";
    }
    else

        while (std::getline(artistFile, a->artistName)) {
            std::cout << a->artistName << "\n";
        }
}

void searchByName() {

}

void searchByGenre() {

}

void searchBySong() {

}

void searchByYear() {

}

The ultimate goal is to display the information and also to be able to search the info based on certain things like the year or artist name or genre. That part of the program I feel comfortable with, but the file reading is really stumping me. A nudge in the right direction would greatly appreciated. Thanks in advance.

I think your approach is good so far. In the struct Discography maybe you could use std::unordered_map<int, std::string> instead, but that's just my opinion. If you know in advance the number of input lines your data is composed of, I strongly recommend changing your istream& operator>>(istream& input, Artist& artist) to use std::getline :

std::istream& operator>>(std::istream& input, Artist& artist)
{
  std::string line;
  std::getline(input, line);
  artist.artistName = line;
  std::getline(input, line);
  auto genres = splitString(line, ';');
  artist.genres = genres;
  std::getline(input, line);
  artist.startingYear = std::stoi(line);
  // etc ...
  return input;
}

To implement std::vector<std::string> splitString(const std::string& str, char delim); you can use this answer . Then you can also think of all kinds of error handling like invalid integer conversion, empty line, not enough lines, etc.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM