簡體   English   中英

從文件 cpp 加載

[英]Loading from file cpp

我想從文本文件加載播放列表。 文本文件由專輯及其歌曲組成,第一行是專輯名稱,第二行是專輯中的歌曲數,然后每行有一首歌曲,直到專輯完成,然后是專輯的專輯名稱下一張專輯等等。為了讓事情更有趣,列表是它自己的 class,專輯它自己的 class 和歌曲他們自己的 class。 這是文件的外觀示例

Album name1

2

song1|artist1|234

song2|artist1|443

Album name2

3

song3|artist2|320

song4|artist2|360

song5|artist2|340

我的問題是,當我加載時,第一張專輯會正確加載,但第二張專輯(和第三張等)不會加載全名,它會錯過第一個字符。 所以專輯名稱 2 將作為 lbum 名稱 2 加載。

這是用於執行此操作的函數和重載所涉及的類:

#ifndef DT019G_JUKEBOX_H
#define DT019G_JUKEBOX_H

#include "Prototypes.h"
#include "Album.h"
#include "Menu.h"

class Jukebox {
private:
    std::vector <Album> albums;
    Menu mainMenu, fileMenu, printMenu;

public:
    Jukebox() {
    void openFile();


void Jukebox::openFile() {
    Album tmpAlbum;
    std::fstream inFile(directory+fileName, std::ios::in);
      while(!inFile.eof()) {inFile>> tmpAlbum;
    albums.push_back(tmpAlbum);}
    inFile.close();
}


#ifndef DT019G_ALBUM_H
#define DT019G_ALBUM_H

#include "Prototypes.h"
#include "Song.h"
class Album {
public:
    std::string albumName;
private:
    std::vector <Song> songList;
public:
    Album() {albumName="NoName";}
    Album(std::string pName) {albumName=pName;}

    //Set/Get functions
    void setAlbumName (const std::string pname) {albumName=pname;}
    void setSongList (const std::vector <Song> pSongList) {songList=pSongList;}
    void clearSongList () {songList.clear();}

    // Add a song to the albums song list
    void addSongToAlbum (const Song pSong);

};

std::istream &operator>>(std::istream &is, Album &album);
#endif //DT019G_ALBUM_H

// Overloads the >> stream so it can be used to load an album from file.
// First it puts all the input in the vector inputData. Then when the first row (containing the album name)
// has been loaded into albumName, the first two entries of inputData are erased (the ones containing the album name and
// number of songs. Then only songs are left in vector thus they can be loaded into the songList with ease.
std::istream &operator>>(std::istream &is, Album &album){
    album.clearSongList();
    std::string tempData;
    std::getline(is, tempData);
    album.setAlbumName(tempData);
    std::getline(is, tempData);
    int numberOfSongs;
    std::istringstream iss(tempData);
    iss >> numberOfSongs;
    Song tempSong;
    for (size_t i=0; i<numberOfSongs; i++){
       std::getline(is, tempData);
       std::istringstream iss(tempData);
       iss>>tempSong;
       album.addSongToAlbum(tempSong);
    }
    is.get();
    return is;
}

我在這里添加歌曲 class 盡管我認為沒有必要,因為 function 似乎符合預期

class Song {
private:
    string title;
    string artist;
    Time length;
public:
    // Default constructor
    Song() {title="noTitle"; artist="noArtist"; length=Time(0,0,0);}
    // Constructor using parameters
    Song (string pTitle, string pArtist, int pHours, int pMinutes, int pSeconds)
    {title=pTitle, artist=pArtist, length=Time(pHours, pMinutes, pSeconds);}

    // Set/Get functions
    void setTitle (string pTitle) {title=pTitle;}
    void setArtist (string pArtist) {artist=pArtist;}
    void setLength (Time pTime) {length=pTime;}
    string getTitle ()const {return title;}
    string getArtist ()const {return artist;}
    Time getLength () const {return length;}

    void clientProgram();
};

// Takes an in stream on the format title | artist | time and convert it to a Song object.
std::istream &operator>>(std::istream &is, Song &song);

#endif //DT019G_SONG_H

std::istream &operator>>(std::istream &is, Song &song){
    string loadData;
    std::getline(is, loadData);
    string tempSeconds;
    Time tempTime;
    size_t j,k,l;
    j=loadData.find(DELIM);
    k=loadData.find(DELIM, j+1);
    l=loadData.size();
    song.setTitle(loadData.substr(0,j));
    song.setArtist(loadData.substr(j+1,k-(j+1)));
    tempSeconds=loadData.substr(k+1, l-(k+1));
    std::istringstream iss(tempSeconds);
    iss >>tempTime;
    song.setLength(tempTime);
    is.get();
    return is;
}

謝謝你的幫助。 我只是找不到自己發生這種情況的原因。

在你的 function

std::istream &operator>>(std::istream &is, Album &album){
    album.clearSongList();
    std::string tempData;
    std::getline(is, tempData);
    album.setAlbumName(tempData);
    std::getline(is, tempData);
    int numberOfSongs;
    std::istringstream iss(tempData);
    iss >> numberOfSongs;
    Song tempSong;
    for (size_t i=0; i<numberOfSongs; i++){
       std::getline(is, tempData);
       std::istringstream iss(tempData);
       iss>>tempSong;
       album.addSongToAlbum(tempSong);
    }
    is.get();
    return is;
}

std::getline()將使用換行符,最后的is.get()將使用 stream 中的下一個字符。 看來這里消耗的是下一張專輯標題的第一個字符。

為避免這種情況,您應該刪除這個額外的is.get(); .

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM