2013-10-20 36 views
0

我有一個文本文件,其中列出像DVD 標題的對象類的某些屬性(字符串) 類別(字符串) 價格(INT) 運行時(INT) 今年發佈的(INT)讀線C++

文件列出像

Movie1 
Action  
10.45 
123 
2008 

Movie2 
Sc-fi 
12.89 
99 
2008 

我有一個功能,讓你在文件的名稱類型,並假定在不同的屬性來讀入一個對象

DVD* file(DVD arr[], string fileName, int s, int& e) 
{ 
ifstream file(fileName); 

DVD j; 
string v; 
string w; 
double x; 
int y; 
int z; 


while(!file.eof()) 
{ 
    file >> v; 
    j.setTitle(v); 

    file >> w; 
    j.setCategory(w); 

    file >> x; 
    j.setPrice(x); 

    file >> y; 
    j.setRuntime(y); 

    file >> z; 
    j.setYear(z); 

    arr=add(arr, j, s, e); //this is just a function that adds the object to an arry 
} 


file.close(); 

return arr; 
} 

,但它不能正常工作,我希望它讀取每行到變量,然後如果有一個空間跳過它,但如果文件未結束前繼續閱讀,直到它擊中的字符串。有什麼建議麼?

回答

1

兩件事。

首先:

while(!file.eof())eof()不返回true直到後試圖讀取時。

的第二件事情是,如果你想讀一行行,最好是用這樣的:

void read_file(std::vector<DVD> & arr, string fileName) { 
    ifstream file(fileName.c_str()); 

    DVD j; 
    std::string line; 
    enum State { 
     TITLE, CATEGORY, PRICE, RUNTIME, YEAR 
    } state = TITLE; 

    while(std::getline(file, line)) { 

     // if we encounter an empty line, reset the state  
     if(line.empty()) { 
      state = TITLE; 
     } else { 

      // process the line, and set the attribute, for example 
      switch(state) { 
      case TITLE: 
       j.setTitle(line); 
       state = CATEGORY; 
       break; 
      case CATEGORY: 
       j.setCategory(line); 
       state = PRICE; 
       break; 
      case PRICE: 
       j.setPrice(boost::lexical_cast<double>(line)); 
       state = RUNTIME; 
       break; 
      case RUNTIME: 
       j.setRuntime(boost::lexical_cast<int>(line)); 
       state = YEAR; 
       break; 
      case YEAR: 
       j.setYear(boost::lexical_cast<int>(line)); 
       arr.push_back(j); 
       state = TITLE; 
       break; 
      default: 
       // just in case 
       state = TITLE; 
       break; 
      } 
     } 
    } 
} 

這工作,因爲std::getline返回一個在布爾上下文中使用會當一個參考如果上一次操作使流處於「良好」狀態,則返回true

在這個例子中,我使用boost::lexical_cast<>來根據需要將字符串轉換爲數字類型,但是您可以使用std::stringstream手動執行此操作,或者您認爲最適合您的任何其他方法。例如,atoi()strtolstrtod

邊注:那最好是使用std::vector<DVD>而不是本機陣列。它會一樣快,但會妥善處理您的大小調整和清理工作。您將不再需要您的add功能,因爲您只需要執行以下操作:arr.push_back(j);

+0

然後,我怎樣才能將每行讀入一個變量。就像我想讓line1(Movie1)上的字符串轉到一個字符串。然後下一行我希望類別(Action)進入另一個字符串 –

+0

只需在循環體中連續多次調用'getline'? –

+0

'line'是你的單一變量。您應該(至少)有一個其他變量來跟蹤程序的狀態並採取適當的行動。 –