C++ 如何将字符串片段读入类数组C++;
我有一个dvd的数组,来自我创建的视频类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
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;
}
}