題目
此次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";
}