我正试图完成C++类入门的作业,但我陷入僵局!该程序应该是一个VHS视频管理器,其中电影存储在结构中。电影是从源文件夹中的.txt文件中获得的,包括电影的标题和年份。读取文本文件后,初始输出应该如下所示:
Initializing Video Collection:
What file should I use? movies.txt
A New Hope (1977)
Empire Strikes Back (1980)
Flight of the Navigator (1986)
Goonies (1985)
Last Crusade (1989)
Raiders of the Lost Ark (1981)
Return of the Jedi (1983)
Temple of Doom (1984)
War Games (1983)
视频存储在如下结构中:
struct Video
{
string title; //the name of the video
int year; // the year the movie was released
int stars; // a rating out of five stars - this will be zero until you set it
bool watched; // starts as false until you watch the movie and flip it to true
};
我似乎不知道如何正确读取文件,因此标题和年份被放置在各自的数组位置。以下是我为此目的所拥有的功能:
void initialize(Video video_array[tapes_max], Video data)
{
ifstream videofile;
videofile.open("movies.txt");
if(videofile.fail())
{
cout << "Could not open states file for reading!" << endl;
exit(1);
}
for(int i = 0; i < tapes_max; i++)
{
getline(videofile, video_array[i].title);
}
videofile.close();
for (int i = 0; i < tapes_max; i++)
{
cout << video_array[i].title << " " << video_array[i].year << endl;
}
cout << endl << endl;
}
这是分配给我的PDF链接,也许你们能比我更好地理解它?提前感谢您的帮助!
https://docs.google.com/open?id=0Bwr7dC-H4CCZUKkyUGNTRzZdk0
因此,您已经将输入行读取为字符串。现在,你需要把它分成两部分:标题和年份。这通常被称为解析:从字符串中提取一些信息。
我想你没有得到一个正式的语法(定义字符串格式的规则集)作为你任务的一部分,但很容易做出一个很好的猜测:这一行包含标题(可能有空格),然后是空格、左括号、发布年份的十进制表示,然后是右括号。
你知道如何解析它吗?一个好的选择是向后扫描字符串:
- 如果最后一个字符不是右括号,请抱怨格式错误;否则,把它剪掉,你已经解析完括号了
- 找到左括号;如果没有人,就抱怨。你必须从结尾开始搜索:标题本身可能包含括号,所以我们感兴趣的左括号一定是最后一个。将文本存储在括号之间(小心索引!):它将是您的
year
- 将年份解析为数字(
atoi
等,请参阅此答案或谷歌了解更多详细信息);如果解析失败,程序必须抱怨输入格式错误 - 砍掉前面的空格,如果找不到空格就抱怨
- 字符串的其余部分必须是视频标题;至少要检查它是否为空
足够解析了,现在Video
对象有了标题和发布年份。其他两个字段目前具有默认值;但是,您的程序必须能够更改它们,并可能序列化它们(用于将信息保存到文件中的一个花哨的词),以便下次用户启动程序时,这些字段的状态得到保留。
这意味着您可能应该为磁盘上的数据发明一种格式,该格式包含所有四个字段(当前的.txt
仅包含其中两个字段)。当然,对于这种格式,您还需要一个解析器。在您的情况下,我个人会使用非常简单的格式:例如,每行只有一个字段。
欢迎来到软件开发的世界!
我认为您应该使用boost::regex
这里有一个演示如何使用regex:处理一行
#include <boost/regex.hpp>
#include <iostream>
#include <string>
#include <cstring>
int main()
{
using namespace std;
string line = "Hey Joe(1984) "; // an example line that you can read
boost::smatch what;
boost::regex e("(.*)\(([0-9]+)\).*"); // whatever comes before numbers in parentheses, is the title.
if(boost::regex_match(line, what, e, boost::match_extra))
{
string title = what[1];
int year = atoi(static_cast<string>(what[2]).c_str()); // perhaps there is a better code for this but it will do.
cout<<"title: "<<title<<"tyear: "<<year<<endl;
}
else
{
cout<<"No match"<<endl; // indicates a wrong line
}
return 0;
}
只要把这个循环起来,你就完成了。
如果你不知道如何使用增强:
安装boost——(在Mac上,我用Mac端口安装了boost)
为我编译行:
g++ -I/opt/local/include -L/opt/local/lib -lboost_regex-mt boost_regex.cpp
# for testing
./a.out
对你来说,窗户上可能有类似的东西。(g++ -IC:pathtoboostincludes -LC:pathtoboostlibs -lboost_regex-something
)。在Windows上,我认为你应该查找一个名为"boost_regex.dll"的dll文件。你可以在boost安装的lib目录中找到该dll。
更多信息:Regex docs