C++ 如何将字符串片段读入类数组C++;

C++ 如何将字符串片段读入类数组C++;,c++,arrays,C++,Arrays,我有一个dvd的数组,来自我创建的视频类 Video dvd[10]; 每个视频都有其属性 class Video { string _title; string _genre; int _available; int _holds; public: Video(string title, string genre, int available, int holds); Video(); void print(); void re

我有一个dvd的数组,来自我创建的视频类

Video dvd[10];
每个视频都有其属性

class Video {
    string _title;
    string _genre;
    int _available;
    int _holds;
public:
    Video(string title, string genre, int available, int holds);
    Video();
    void print();
    void read(istream & is, Video dvd);
    int holds();
    void restock(int num);
    string getTitle();
    ~Video();
};
我试图用文本文件中的数据填充这个数组,其中每个信息(如标题和流派)都用逗号分隔

Legend of the seeker, Fantasy/Adventure, 3, 2
Mindy Project, Comedy, 10, 3
Orange is the new black, Drama/Comedy, 10, 9
我尝试过使用getline(in,line,,”)但是当我要将每一行插入dvd阵列时,我的大脑就会停止

我还创建了一个read方法来读取由空格分隔的每个单词,但我认为这不是我真正想要的

我还尝试用getline读取一行,将该行存储在字符串中并从中拆分,但我对这行感到困惑

**我可以从每行中获得所需的字符串,我的困惑在于如何将其插入while循环中的类数组中,尤其是当我一次只能读取一个单词时

我需要帮助,我应该采取什么方法来解决这个问题

**我的代码

#include <iostream>
#include <fstream>
#include <cassert>
#include <vector>

#define MAX 10

using namespace std;

class Video {
    string _title;
    string _genre;
    int _available;
    int _holds;
public:
    Video(string title, string genre, int available, int holds);
    Video();
    void print();
    void read(istream & is, Video dvd);
    int holds();
    void restock(int num);
    string getTitle();
    ~Video();
};

Video::Video(string title, string genre, int available, int holds){
    _title = title;
    _genre = genre;
    _available = available;
    _holds = holds;
}

void Video::read (istream & is, Video dvd)   
{  
    is >> _title >> _genre >> _available>>_holds;
    dvd = Video(_title,_genre,_available,_holds);

}

int Video::holds(){
    return _holds;
}

void Video::restock(int num){
    _available += 5;
}

string Video::getTitle(){
    return _title;
}

Video::Video(){

}

void Video::print(){
    cout<<"Video title: " <<_title<<"\n"<<
    "Genre: "<<_genre<<"\n"<<
    "Available: " <<_available<<"\n"<<
    "Holds: " <<_holds<<endl;
}

Video::~Video(){
    cout<<"DESTRUCTOR ACTIVATED"<<endl;
}

int main(int params, char **argv){

    string line;
    int index = 0;
    vector<string> tokens;
    //Video dvd = Video("23 Jump Street", "comedy", 10, 3);
    //dvd.print();
    Video dvd[MAX];
    dvd[0].holds();

    ifstream in("input.txt");

    /*while (getline(in, line, ',')) {
        tokens.push_back(line);

    }
    for (int i = 0; i < 40; ++i)
    {
        cout<<tokens[i]<<endl;
    }*/

    if(!in.fail()){
        while (getline(in, line)) {

            dvd[index].read(in, dvd[index]);
            /*cout<<line<<endl;
            token = line;
            while (getline(line, token, ',')){

            }
            cout<<"LINE CUT@@@@@"<<endl;
            cout<<line<<endl;
            cout<<"TOKEN CUT@@@@@"<<endl;*/
            //dvd[index] = 
            index++;
        }
    }else{
        cout<<"Invalid file"<<endl;
    }


    for (int i = 0; i < MAX; ++i)
    {
        dvd[i].print();
    }


}
#包括
#包括
#包括
#包括
#定义最大值10
使用名称空间std;
课堂录像{
字符串标题;
弦乐体裁;
int_可用;
国际控股公司;
公众:
视频(字符串标题、字符串类型、整数可用、整数保持);
视频();
作废打印();
无效读取(istream&is、视频dvd);
int holds();
无效补货(整数);
字符串getTitle();
~Video();
};
视频::视频(字符串标题、字符串类型、整数可用、整数保留){
_头衔=头衔;
_体裁=体裁;
_可用=可用;
_保持=保持;
}
无效视频::读取(istream&is,视频dvd)
{  
是>>\u标题>>\u流派>>\u可用>>\u持有;
dvd=视频(标题、流派、可用、保留);
}
int视频::holds(){
返回持有;
}
void Video::重新进货(int num){
_可用+=5;
}
字符串视频::getTitle(){
返回标题;
}
视频::视频(){
}
void Video::print(){

cout首先,我将
Video::read
函数更改为
operator>
的重载。这将允许在使用输入流时像使用任何其他类型一样简单地使用
Video

另外,将
read
实现为返回
void
的非静态成员函数的方式并不直观,而且使用起来非常笨拙。如何编写循环,同时检测到已到达文件末尾(想象一下,如果只有3个项目可以阅读,你怎么知道不去读一个第四个项目)?更好,直观,坦率地说,事实上,在C++中这样做是为了过载<代码> > /代码>运算符。 (在最后,我将演示如何编写一个使用重载的
>
读取
函数)

我不会解释为什么这应该是一个
朋友
函数,因为这里可以很容易地研究如何重载
>

因此,我们需要实现这个函数。下面是一个实现,它在一行中读取信息,并将信息复制到传入的
vid

std::istream& operator >> (std::istream& is, Video& vid)
{
    std::string line;
    std::string theTitle, theGenre, theAvail, theHolds;

    // First, we read the entire line
    if (std::getline(is, line))
    {
        // Now we copy the line into a string stream and break 
        // down the individual items
        std::istringstream iss(line);

        // first item is the title, genre, available, and holds
        std::getline(iss, theTitle, ',');
        std::getline(iss, theGenre, ',');
        std::getline(iss, theAvail, ',');
        std::getline(iss, theHolds, ',');

       // now we can create a Video and copy it to vid
       vid = Video(theTitle, theGenre, 
                   std::stoi(theAvail), // need to change to integer
                   std::stoi(theHolds)); // same here
    }
    return is;  // return the input stream
}
请注意,
vid
是一个参考参数,不是通过值传递的。如果要保留它,您的
read
函数需要进行相同的更改

我们在上面所做的是首先使用对
std::getline
的“外部”调用读取整行。一旦我们将该行作为字符串,我们将使用
std::istringstream
分解该字符串,并使用“内部”分隔逗号上的每个项目在
istringstream
上工作的一组
getline
调用。然后,我们只需根据从
istringstream
检索到的信息创建一个临时
视频
,并将其复制到
vid

下面是一个
main
函数,现在最多可读取10项:

int main()
{
    Video dvd[10];
    int i = 0;
    while (i < 10 && std::cin >> dvd[i])
    {
        dvd[i].print();
        ++i;
    }
}
这是
的主要功能:

int main()
{
    Video dvd[10];
    int i = 0;
    while (i < 10 && dvd[i].read(std::cin, dvd[i]))
    {
        dvd[i].print();
        ++i;
    }
}
intmain()
{
视频dvd[10];
int i=0;
而(i<10&&dvd[i].read(std::cin,dvd[i]))
{
dvd[i].print();
++一,;
}
}


然而,我仍然认为,制作
Video::read
非静态成员会使
main
中的代码变得笨重。

现在将是学习正则表达式的好时机。此外,用户定义的
Video
析构函数有什么用途?所有
Video
类中的成员销毁时不需要任何特殊处理。我已经尝试了这个问题的答案。使用字符串向量来存储值,但我不能在dvd数组的每个实例中使用它@ChristopherPiszI可以从每一行获得我需要插入的所有字符串,困惑在于如何将其插入我的数组。啊!我现在明白了大局。谢谢保罗
bool Video::read(std::istream & is, Video& dvd)
{
    if (is.good())
    {
        is >> dvd;
        return true;
    }
    return false;
}
int main()
{
    Video dvd[10];
    int i = 0;
    while (i < 10 && dvd[i].read(std::cin, dvd[i]))
    {
        dvd[i].print();
        ++i;
    }
}