C++ 讀寫檔案練習


題目

此次project建立在計算機實習05 Practice的題目之上,希望你用C++打造一個評分系統,要能夠讀入「score.txt」,並將能否通過中央資工一階篩選門檻的結果寫入「output.txt」中。詳細說明如下:

成績標準:
int stander[4]={12,12,8,12};

(1) 資料解說
「score.txt」中的資料可能會有可能會有1~無限多筆,而其中一行代表一筆學生的學測成績,如下圖所示:
John 12 12 14 15
Mary 11 14 10 8
Kevin 13 14 8 13
Jesse 4 10 18 7

以此筆範例來說,裡面包含著四個考生的學測成績,其中
John成績依序為:國文12級分、英文12級分、數學14級分、自然15級分;Mary成績依序為:國文11級分、英文14級分、數學10級分、自然8級分;Kevin成績依序為:國文13級分、英文14級分、數學8級分、自然13級分;Jesse成績依序為:國文11級分、英文14級分、數學10級分、自然8級分。
你的程式應該要能使用一個二維陣列將多筆學生資料儲存起來。

「cmd.txt」中的資料可能會有可能會有1~無限多筆,而其中一行代表欲搜尋的學生姓名以及要搜尋的科目名稱(chinese, english, math, science,都是小寫),如下圖所示:
John chinese
Kevin math

以此筆範例來說,裡面包含著兩個command,分別是:搜尋John的chinese(國文)成績、以及搜尋Kevin的math(數學)成績。你的程式應該要能夠讀懂cmd的要求並找出此學生的當科成績。

(2)
The actual input and output for running your program is something that looks like the following:
例一:
score.txt自此始,但不包括此行
John 12 12 14 15
Mary 11 14 10 8
Kevin 13 14 8 13
Jesse 4 10 18 7
score.txt至此止,但不包括此comment

output.txt自此始,但不包括此行
Hello John, welcome to NCU CSIE!
Sorry, Mary can't enter NCU CSIE.
Hello Kevin, welcome to NCU CSIE!
Sorry, Jesse can't enter NCU CSIE.

output.txt至此止,但不包括此comment

完整程式碼

 #include<iostream>
#include<fstream>
#include<string>
#include <sstream>
#include<vector>
using namespace std;

//二維vector : https://ramihaha.tw/c-program-container-vector-array-linklist/
//           : https://shengyu7697.github.io/std-vector/
//文件讀取 : https://blog.csdn.net/guowenyan001/article/details/11231927
//string切割 : https://shengyu7697.github.io/cpp-string-split/
//文件寫入 : https://shengyu7697.github.io/cpp-write-text-file/
//string 轉 int : https://www.programiz.com/cpp-programming/string-int-conversion

vector<string> split(const string &s, char delimiter) {
    vector<string> tokens;     
    string token;     
    istringstream tokenStream(s);     
    while (getline(tokenStream, token, delimiter)) {      
        tokens.push_back(token);     
    }     
    return tokens;  
}


int main(){

    //標準分數array
    int stander[4]={12,12,8,12};  

    //1.建立可以存score.txt資料之vector
    vector<vector<string>> scoreData;

    //2.讀取的score.txt文件內容
    ifstream readScore;
    readScore.open("score.txt",ios::binary);

    //3.將score.txt資料存入scoreDate中
    string line;  //文件內容一行行讀取
    while(getline(readScore,line)){
        vector<string> to_scoreData = split(line, ' ');
        scoreData.push_back(to_scoreData);
    }

    readScore.close();

    //4.將Scoredata run一次,把入學檢測結果寫入output.txt
    ofstream toOutput;
    toOutput.open("output.txt");

        //無法寫入的處理程序

    if (!toOutput.is_open()) {
        cout << "Failed to open file.\n";
        return 1; // EXIT_FAILURE
    }

        //可以寫入的程序處理

    for(int i=0;i<scoreData.size();i++){
        //1為全都過 ,0為沒過
        int flag=1;
        for(int j=0;j<4;j++){

            //string --> int
            string score = scoreData[i][j+1];
            int scoreInt;
            scoreInt= std::stoi(score);
            if(scoreInt < stander[i]){
                flag=0;
                break;
            }
        }

        string name = scoreData[i][0];
        //錄取成功的輸出值
        if(flag) toOutput << "Hello " << name << ", welcome to NCU CSIE!\n";
        //錄取失敗的輸出值
        else toOutput << "Sorry, " << name << " can't enter NCU CSIE.\n";
    }

    //關掉輸出stream
    toOutput.close();

    return 0;
}

解題觀念及思路

1.vector

一種更便利的array:
定義初始vector時不用宣告array大小 --> 用於變動空間array的情境
因此題目要求從score.txt輸入不定量資料時就適合用vector來存放

vector<vector<string>> scoreData;

2.讀入檔案資料

stream 資料流的概念:

file inputstream建立:

ifstream readScore;
readScore.open("score.txt",ios::binary);

接下來將file內容一行行讀入程式中
直到程式碼讀完file中的所有內容

string line;  //文件內容一行行讀取
while(getline(readScore,line)){
    ...
}

readScore.close();

讀入行內容依space分解成單字
回傳一個vector< string>裡面存著分解好詞之陣列
e.g.
line = "We say hello world.";
vector< string> words = split(line, ' ');
words-->["We", "say", "hello", "world"]

vector<string> to_scoreData = split(line, ' ');
vector<string> split(const string &s, char delimiter) {
    vector<string> tokens;     
    string token;     
    istringstream tokenStream(s);     
    while (getline(tokenStream, token, delimiter)) {      
        tokens.push_back(token);     
    }     
    return tokens;  
}

3.將資料寫入檔案

file outputstream建立:

ofstream toOutput;
toOutput.open("output.txt");

資料寫入文件

//錄取成功的輸出值
if(flag) toOutput << "Hello " << name << ", welcome to NCU CSIE!\n";
//錄取失敗的輸出值
else toOutput << "Sorry, " << name << " can't enter NCU CSIE.\n";

fileoutputstream << data -->就能將data寫入文件
最後不使用要關閉 --> fileoutputstream.close();

4.判斷是否能入學

要全部科目都過標準才能入學
一開始假設每位學生都可以入學 flag=1
只有驗到有科目沒過標準就 flag=0 並 break換檢查下位學生

for(int i=0;i<scoreData.size();i++){
        //1為全都過 ,0為沒過
        int flag=1;
        for(int j=0;j<4;j++){
            //string --> int
            string score = scoreData[i][j+1];
            int scoreInt;
            scoreInt= std::stoi(score);
            if(scoreInt < stander[i]){
                flag=0;
                break;
            }
        }
        string name = scoreData[i][0];
        //錄取成功的輸出值
        if(flag) toOutput << "Hello " << name << ", welcome to NCU CSIE!\n";
        //錄取失敗的輸出值
        else toOutput << "Sorry, " << name << " can't enter NCU CSIE.\n";
    }







你可能感興趣的文章

類別繼承範例

類別繼承範例

CSS 元素置中大全

CSS 元素置中大全

Vue3使用pinia之用法

Vue3使用pinia之用法






留言討論