[英]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.