2013-09-27 37 views
-1

說我有像幾行這樣的C++讀取文件到類variables```

H 2012/08/05 20 13 Homework 1 
Q 2012/08/07 10 8.5 Quiz 1 
L 2012/08/05 5 3 Lab 1 Attendance 

的開頭字母代表(H)作業,(Q或E)測驗/考試的文本文件,並(L)Labs 我想將每個值讀入相應的類變量,然後按字母順序對它們進行排序,然後將它們打印到自己的類別中: 這裏是我設置的類。

class Assignment 
{ 
private: 
     char Assignment_type; 
     string Date; 
     int Max_score; 
     float Actual_score; 
     string Assignment_name; 
public: 
     Assignment(); 
} 

顯然我沒有寫返回值或默認的構造函數的功能呢,我真的只是需要一些幫助搞清楚如何從文件中讀取到正確的變量第一。

一旦閱讀,我需要能夠按字母順序對它們進行排序,然後將它們打印到相應的類別中。

如何在將這種數據讀入正確的變量後按字母順序排序?

+0

使用'std :: sort'。 :v – rightfold

+0

要存儲到類變量中的「價值」是什麼? – MadeOfAir

+0

Assignment_type =「H」,Date =「2012/08/05」,Max_score =「20」,Actual_score =「13」,第一行Assignment_name =「作業1」 – nastalgia

回答

3

您可以std::getlinestd::istringstream和其他幾個標準庫的功能做到這一點:

class Assignment 
{ 
    // ... 

public: 

    friend std::istream& operator>>(std::istream& is, Assignment& assignment) 
    { 
     std::string line; 
     std::getline(is, line); 

     std::istringstream iss(line); 

     iss >> assignment.Assignment_type; 
     iss >> assignment.Date; 
     iss >> assignment.Max_score; 
     iss >> assignment.Actual_score; 

     // The last field is a little difficult, as it should get the rest 
     // of the line, which can include spaces, and the `>>` operator 
     // separates on spaces 
     // Get the rest using `getline` 
     std::getline(iss, assignment.Assignment_name); 

     return is; 
    } 
}; 

現在你可以做如

std::ifstream input_file("data.txt"); 

Assignment assignment; 

input_file >> assignment; 

參考文獻:


對於另一部分,您應該將新讀取的Assigment對象置於類似std::vector的集合中。然後你可以使用std::sort對它們進行排序不過你想要的:

std::vector<Assignment> assignments; 

std::ifstream input_file("data.txt"); 
Assignment assignment; 
while (input_file >> assignment) 
    assignments.push_back(assignment); 

std::sort(std::begin(assignments), std::end(assignments)); 

對於std::sort功能工作,你必須實現爲您分配一個operator<雖然:

class Assignment 
{ 
    // ... 

public: 

    friend bool operator<(const Assignment& a, const Assignment& b) 
    { 
     return a.Assignment_name < b.Assignment_name; 
    } 
}; 

如果你有一個C + +11(或更好)兼容的編譯器,那麼你可以使用lambda expressions(見Wikipedia)調用std::sort時:

std::sort(std::begin(assignments), std::end(assignments), 
    [](const Assignment& a, const Assignment& b) 
    { 
     return a.Assignment_name < b.Assignment_name; 
    }); 

參考文獻:

+0

非常感謝。 – nastalgia

+1

您可以將調用鏈接到'>>',用'getline()'替換'copy()'調用,並將'less'參數的默認值'sort()'移除。 –

+0

@JonPurdy對我來說太早,但是我絕對可以。會在一些早餐或什麼之後做。 :) –

1

要閱讀你的數據好像你應該只是做正常的事情

std::istream& operator>>(std::istream& in, Assignment& a) 
{ 
    in >> a.Assignment_Type >> a.Date >> a.Max_score >> a.Actual_score; 
    getline(in, a.Assignment_name); 
    return in; 
} 

唯一稍微棘手的部分是,你的任務名稱可以包含空格,所以我用函數getline讀的那部分。

該函數必須是Assignment的朋友才能訪問其私有變量。

class Assignment 
{ 
    friend std::istream& operator>>(std::istream& in, Assignment& a); 
    ... 
}; 

作爲排序數據,只要把它在載體中,並調用std::sort與合適的分類條件。

bool compare(const Assignment& x, const Assignment& y) 
{ 
    return ...; // return true if x is 'less than' y alphabetically 
} 

std::vector<Assignment> data; 
... 
std::sort(data.begin(), data.end(), compare); 
+0

謝謝你約翰 - 瘋狂的幫助 - 即時通訊使用getline雖然,它只是沒有讀入a.Assignment_name。有什麼想法嗎? – nastalgia

+0

@nastalgia不是馬上,getline會從文件中的當前位置讀取所有內容到行尾。當你得到這樣的錯誤時,你必須始終認爲錯在哪裏不是閱讀分配名稱,而是你正在做什麼來寫出它。如果你無法弄清楚這聽起來像是一個新問題。 – john

0

,你應該這樣做以下,並存儲在相應的類變量每個令牌。

char buff[50]; char *temp; 
while(in.getline(buff,50,'\n')) 
    { 


     Asignment_type = strtok(buff," "); 

     int count = 4; 
     while(count>0) 
     { 
      temp = strtok(NULL," "); 

      count--; 

     } 

    } 

第一個令牌會給你賦值類型,而在內部的同時,每個temp會給你更多的令牌,每行。你可以將它們存儲在相應的變量中。 (想想你將如何存儲完整的作業名稱)。祝你好運。

+1

不,不,不! **不要**'while(!in.eof())',它不會像你期望的那樣工作,並且會循環一次到很多次。原因是EOF標誌將不會被設置,直到*嘗試從文件結束之外讀取之後。 –

+0

@JoachimPileborg謝謝。 ''會循環一次到多少'是什麼意思?在這種情況下你會提出什麼樣的替代方案? – Zeeshan

+1

對於最後一行,'getline'調用不*設置EOF標誌。所以循環會繼續,導致getline失敗(現在EOF標誌被設置),但是你仍然使用字符串,因爲它包含有效數據。相反,例如'while(in.getline(...))'。 –