2015-06-21 58 views
0

目前我正面臨一個大問題,我需要將數據填充到MAP並將其寫入文件。如何不覆蓋MAP C++中的現有數據?

該文件將是這個樣子:

Name StudentNo Gender Indian English Math History Moral Average 
Dragon 33899  M  100  100 100 100  100  100 

下面的代碼

// Function to modify a student's exam scores. 
    void Student::modifyScore(string newName, int newStudentNo, char newGender, int newIndian, int newEnglish, int newMath, int newHistory, int newMoral) { 


    map<string, tuple<int, char,int, int, int, int, int> > data; 

    // Read file and fill data map 
    ifstream studentRec("StudentRecord.txt"); 
    string line; 

    while (getline(studentRec, line)) 
    { 
     string name; 
     int studentNo; 
     char gender; 
     int indian, english, math, history, moral; 
     stringstream ss(line); 
     ss >> studentNo>>gender>>name >> indian >> english >> math >> history >> moral; 
     data[name] = make_tuple(studentNo, gender,indian, english, math, history, moral); 

    } 

    studentRec.close(); 
    auto it = data.find(newName) ; 
    if (it == data.end()) // student not in map, that's an error 
     return ; 
    // now it->second holds your student data, 
    int studentNo = get<0>(data-second) ; 
    char gender = get<1>(data->second) ; 
    // Modify data 
    data[newName] = make_tuple(newStudentNo, newGender ,newIndian,newEnglish, newMath, newHistory, newMoral); 
    // Open same file for output, overwrite existing data 
    ofstream ofs("StudentRecord.txt"); 

    for (auto entry = data.begin(); entry != data.end(); ++entry) 
    { 
     tie(newStudentNo, newGender,newIndian,newEnglish, newMath, newHistory, newMoral) = entry->second; 
     int average = averageScore(newIndian,newEnglish, newMath, newHistory, newMoral); 

     ofs << left << setw(15) << entry->first << setw(15) <<newGender<<newName<< newIndian << setprecision(2) << newEnglish << setw(15) << right << newMath << setw(15) << newHistory << setw(15) << newMoral << average << endl; 
    } 
    ofs.close(); 


} 

這段代碼的問題是,我要補充studentNo性別作爲參數的功能,那麼只有它會覆蓋文件,但我真正想要的只是輸入一個名稱,然後修改每個主題的分數。

示例我真正想要的。

任何修改之前

Name StudentNo Gender Indian English Math History Moral Average 
    Dragon 33899  M  100  100 100 100  100  100 

提詞

Enter the name of the student: // It will find the map that has name Dragon 
    --> Dragon 

Enter the new score for indian subject 
    --> 77 

Enter the new score for English subject 
    --> 55 

Enter the new score for Math subject 
    --> 100 

Enter the new score for History subject 
    --> 89 

Enter the new score for Moral subject 
    --> 62 

修改後

 Name StudentNo Gender Indian English Math History Moral Average 
    Dragon 33899  M  77  55 100 89  62  76.6 

正如你所看到的學生沒有性別仍然存在,沒有我需要輸入的值。唯一改變的是主題分數。我將如何完成這個輸出?目前我的代碼將始終需要我輸入studentNo性別以及輸入。

+0

'data [newName]'覆蓋循環的每次迭代中相同的鍵,因爲您永遠不會更改它。 –

+0

但是,我如何堅持studentNo和性別值爲一個指定的學生密鑰? – airsoftFreak

回答

1

給定的名稱,你可以得到一個迭代器是學生,然後得到的原始數據

auto it = data.find(name) ; // gets current student record from the map 
if (it == data.end()) // student not in map, that's an error 
    return ; 
// now it->second holds your student data 
// an auto here could be better, but we want to be sure of type 
studentNo = get<0>(it->second) ; 
gender = get<1>(it->second) ; 
+0

我得到了一些錯誤,再次檢查我的修改代碼,我將名稱更改爲newName,因爲名稱必須先初始化。 - >沒有重載函數的實例「get」匹配參數列表(錯誤) – airsoftFreak

+0

我應該在哪裏放這個代碼? – airsoftFreak

+0

*您已閱讀輸入文件後,必須插入代碼*。請記住退休忍者的建議。 get <>是std :: tuple頭部的一部分(參見http://en.cppreference.com/w/cpp/utility/tuple) – marom

0

假設你想更新StudentNo與名字「龍」你可以做學生記錄如下:

int NewStudentNo; 
string NewName="Dragon"; 

auto it = data.find(NewName) ; // gets current student record from the map 
if (it == data.end()) // student not in map, that's an error 
    return ; 
std::cout<<"Enter new student Number"; 
std::cin>>NewStudentNo; 
std::get<0>(it->second) = NewStudentNo; 
+0

但如果我不想更新studentNo和gender?,我需要更新的只是主題 – airsoftFreak

+0

相應地更改索引,例如對於印度'get <2>(it-> second)= newIndian' – Steephen