2012-11-16 45 views
-1

我正在嘗試完成我的介紹給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-H4CCZUkkyUGNTRzRZdk0

+5

到目前爲止,您已將整個輸入行讀取爲一個字符串。現在你需要_parse_那個字符串 - 分成'title'和'year'部分。對?之後,你最好將年份從字符串轉換爲int。 – Vlad

+1

沒有函數可以將一行直接放入結構中,您必須知道它的外觀,然後相應地解析它。 – SinisterMJ

+2

你大約是家庭的1/3。您打開數據文件,讀取行,並將其填入集合中。現在您需要爲電影標題名稱和年份解析每行,並在結構中正確存儲。排名和觀看狀態完全取決於你。 – WhozCraig

回答

2

所以,你讀過的輸入行成一個字符串。現在,您需要將其分爲兩部分:標題和年份。這通常被稱爲解析:從字符串中提取一些信息。

我假設你沒有得到一個正式的語法(定義你的字符串格式的規則集)作爲你的任務的一部分,但是很容易做出一個很好的猜測:該行包含標題(可能帶有空格),然後是空格,左括號,發佈年份的十進制表示,然後是右括號。

你看到如何解析它嗎?一個好的選擇是向後掃描字符串:

  1. 如果最後一個字符不是右括號,則抱怨格式錯誤;否則,切斷它,你已經完成了解析括號。
  2. 找到左括號;如果沒有人,抱怨。你必須從最後搜索:標題可能包含自己的括號,所以我們感興趣的左括號必須是最後一個。在圓括號之間存儲文本(小心索引!):這將是您的year
  3. 將年份解析爲數字(atoi之類,請參閱this answer或Google瞭解更多詳情);如果解析失敗,程序必須抱怨錯誤的輸入格式
  4. 砍掉前面的空格並抱怨如果沒有找到空格
  5. 其餘的字符串必須是視頻標題;至少檢查一下它不是空的。

足夠解析,現在你的Video對象有一個標題和一個發佈年份。其他兩個字段現在具有默認值;但是,您的程序必須能夠更改它們,並且可能會將它們(將信息保存到文件中的花式詞)序列化爲,以便下次用戶啓動程序時,這些字段的狀態將被保留。

這意味着也許您應該在包含所有四個字段的磁盤上創建數據格式(當前的.txt僅包含其中的兩個)。當然你也需要一個解析器。我個人會在你的情況下使用非常簡單的格式:例如,每行只有一個字段。

歡迎來到軟件開發的世界!

0

我想你應該使用boost :: 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上,我安裝了MacPorts的提升)

編譯行對我來說:

g++ -I/opt/local/include -L/opt/local/lib -lboost_regex-mt boost_regex.cpp 
# for testing 
./a.out 

對於你可能會在窗口上看到類似的東西。 (g++ -IC:\path\to\boost\includes -LC:\path\to\boost\libs -lboost_regex-something)。在Windows上,我認爲你應該查找一個名爲「boost_regex.dll」的dll文件。您可以在升級安裝的lib目錄中找到dll。

更多信息:Regex docs