通訊錄整包讀寫(延伸)
0.5s 256M〔初探結構體:班級通訊錄〕的評測程式得逐成員 cin >> a[i].name >> a[i].seat >> a[i].phone 才讀得進一位同學——因為沒人教過 cin 一個 student 長什麼樣。這題請你教會它:讓 cin >> s、cout << s 直接成立,整包讀、整包印。
延伸知識:本題練的是 14.8 運算子多載:輸入與輸出。不會這招也沒關係——用 14.4 的成員函式
read()/print()一樣能解掉本單元的其他題目。
請定義結構體 student,並在結構體外面多載兩個運算子。名稱、型態、簽名都必須完全一樣:
| 項目 | 型態/簽名 | 意義 |
|---|---|---|
name |
string |
姓名(小寫英文字母) |
seat |
int |
座號 |
phone |
string |
電話(恰 \(10\) 個數字,可能以 0 開頭) |
operator >> |
istream& operator >> (istream &is, student &s) |
從 is 依序讀入 s 的姓名、座號、電話,最後 return is; |
operator << |
ostream& operator << (ostream &os, const student &s) |
把 座號 姓名 電話(以一個空白分隔)印到 os,不要換行,最後 return os; |
>>、<< 的左邊是 cin/cout,不是你的結構體,所以這兩個函式不能寫成成員函式,要寫在結構體外面。你只需要寫結構體定義與這兩個函式,不用寫 main、不用 #include 任何東西——評測程式會自動在你的程式最上方加上這題需要的標頭(<iostream>、<string>)與 using namespace std;,要用其他標頭自己再 #include 即可。想把含有 main 的完整程式貼上來測試也可以,評測時會忽略你的 main。
可以直接複製下面的骨架來改:
struct student {
// 在這裡宣告三個成員
};
istream& operator >> (istream &is, student &s) {
// 從 is 讀入 s 的三筆資料
return is;
}
ostream& operator << (ostream &os, const student &s) {
// 把「座號 姓名 電話」印到 os,不換行
return os;
}
評測程式會做的事
評測程式會 #include 你的程式,然後:
- 宣告
student s;與vector<student> v;。 while (cin >> s) v.push_back(s);——用你的>>一位一位讀,直到輸入結束(EOF)。輸入沒有給行數,while全靠>>回傳的 stream 判斷該不該停,所以return is;不能少。- 從最後一位倒著印:
cout << v[i] << '\n';——用你的<<印一位同學,換行由評測程式補。
若不符合規格,編譯訊息的第一行會告訴你缺了什麼,例如 [檢查] operator << 的第二個參數要是 const student &。
輸入格式
(這是評測程式讀的輸入。)若干行,每行依序是一位同學的姓名、座號、電話,以一個空白分隔。沒有告訴你共有幾行,讀到輸入結束為止。
限制
- 至少 \(1\) 行、至多 \(1000\) 行
- 姓名由 \(1\) 到 \(10\) 個小寫英文字母組成
- \(1 \le\) 座號 \(\le 1000\)
- 電話恰為 \(10\) 個數字(
0到9),可能以0開頭
輸出格式
依名單倒過來的順序,每位同學印一行 座號 姓名 電話,以一個空白分隔。
範例輸入 1
amy 3 0912345678
bob 7 0987654321
cathy 1 0900000000
範例輸出 1
1 cathy 0900000000
7 bob 0987654321
3 amy 0912345678
範例解釋 1
輸入沒有行數,評測程式靠 while (cin >> s) 讀到第 \(3\) 行之後遇到 EOF 停下,再倒過來印。你的 << 只負責印 座號 姓名 電話——如果自己多印了換行,每兩筆之間就會多出一個空行。