2015-06-22 30 views
0

我想覆蓋文件中的數據,輸入一定的值後使用cin。我面臨的問題是,應該修改文件的功能實際上並沒有正確執行。數據輸出奇怪的數字到文件,MAP C++

這裏的情況,我用寄存器功能

代碼添加這些數據:

// register a student to the system 
void Student::registerStudent(string name, int studentNo, char gender) { 
     outStream.open("StudentRecord.txt", ios_base::app); 
     outStream << left << setw(15) << studentNo << setw(15) << gender << right << name << endl; 
     outStream.close(); 
} 

我增加了數據的3倍,我得到

Batman 11 M 
    BatGirl 22 F 
    Joker 33 M 

現在問題來了,我試圖修改蝙蝠俠行添加額外的主題分數

,我想要的結果:後

Batman 11 M 100 22 55 22 33 
    BatGirl 22 F 
    Joker 33 M 

數量的名稱是主體分數。

然而,當我運行程序來修改特定行我得到這個

BatGirl  22    F    -858993460  -858993460   -858993460  -858993460  -858993460 
Batman   11    M    12    86       44    24    55 
Joker   33    M    -858993460  -858993460   -858993460  -858993460  -858993460 

下面是具體的線條修飾

// Function to modify a student's exam scores. 
    void Student::modifyScore(string newName, 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 >> name >> studentNo>> gender>> indian >> english >> math >> history >> moral; 
     data[name] = make_tuple(studentNo, gender,indian, english, math, history, moral); 

    } 

    studentRec.close(); 
    // Modify data 


    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 ; 
    // now it->second holds your student data 
    // an auto here could be better, but we want to be sure of type 
    auto studentNo = get<0>(it->second) ; 
    auto gender = get<1>(it->second) ; 

    data[newName] = make_tuple(studentNo, gender, 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(studentNo, gender, newIndian,newEnglish, newMath, newHistory, newMoral) = entry->second; 
     //int average = averageScore(newIndian,newEnglish, newMath, newHistory, newMoral); 

     ofs << left << setw(15) << entry->first << setw(15) << studentNo << setw(15) << gender << setw(15) << newIndian << setw(15) << newEnglish << setw(15) << right << newMath << setw(15) << newHistory << setw(15) << newMoral << endl; 
    } 
    ofs.close(); 


} 

代碼爲清楚起見爲參數modifyScore

newName --> is to find the name in the file 
newIndian --> Subject scores 
newEnglish --> Subject scores 
newMath --> Subject scores 
newHistory --> Subject scores 
newMoral --> Subject scores 

請指出我犯了錯誤的地方。謝謝!

+0

行。如果你問一個流中提取一個數字,它不能,因爲沒有一個號碼在該位置在流中,它失敗了,你希望提取數字的變量沒有改變。在你的情況下,這些變量也是未初始化的,所以它們可以包含任何東西。在數字不存在的情況下,不知道你期望什麼,很難提供建議。 –

回答

0

問題是

stringstream ss(line); 
    ss >> name >> studentNo>> gender>> indian >> english >> math >> history >> moral; 

當遇到一個3字線像Batman 11 M,表達ss >> indianwill fail and activate the failbit。這意味着印度之後的所有變量都不會被修改。就目前而言,它們是未初始化的,它解釋了你得到的值的隨機性。

現在要解決這個問題,您應該檢測特定行中的列數,即number of words in the string,以便您可以將未修改行的狀態恢復到其先前狀態。

unsigned int countWordsInString(std::string const& str); 

bool fullrecord(std::string const& str) 
{ 
    return countWordsInString(str) == 8; 
} 

map<string, tuple<int, char,int, int, int, int, int, bool> > data; //added bool 
stringstream ss(line); 
bool hasGrades = fullrecord(line); 
if(hasGrades) 
    ss >> name >> studentNo>> gender>> indian >> english >> math >> history >> moral; 
else 
    ss >> name >> studentNo>> gender; 
data[name] = make_tuple(studentNo, gender,indian, english, math, history, moral, hasGrades); 

現在使用布爾來決定是否保存有或無等級