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