<style> .reveal .slides { text-align: left; font-size:30px } </style> # Advanced IO ---- - int/ long long - char and ascii - string compare - getline - stringstream - setw - setprecision - ceil/floor/round - IO 優化 ---- ## int / long long int 所能儲存的範圍為 -2,147,483,648 至2,147,483,647 約為 $\pm 2\cdot 10^9$ long long 為 -9223372036854775808 ~ 9223372036854775807 約為 $\pm 9\cdot 10^{18}$ ---- ## char and ASCII 一個 char 變數 就是儲存 [ASCII](https://www.asciitable.com/) 裡的一個整數編號 char / int 轉換 ```cpp= char c = 'c'; cout << (int)c << endl; cout << (char)66 << endl; c -= 2; cout << c << endl; ``` ---- ## 字串比較 兩個字串 $s$ 和 $t$ 比較大小, 會從頭開始比較,比較到第一個不同的字元為止,或者字串結束 s < t ``` s = "abdee" t = "abfa" ``` s > t ``` s = "abdfee" t = "abdfe" ``` s == t ``` s = "abc" t = "abc" ``` ---- ## getline() #include\<string\> 讀取一整行的輸入(包括空白) 用法 ```cpp= string str; getline(cin, str); ``` ---- ## cin 與 getline 混用 ```cpp= int x; string y; cin >> x; getline(cin, y); ``` 如果讀以下輸入 ``` 123 abc ``` 會發現 y 是空的 ---- 由於 cin 會讀到非整數的字元為止,所以會停在換行, 而 getline 會讀到換行,因此會只把 cin 剛剛的空白吃掉而已, 因此在 cin 後要使用 getline 的話,需要先把換行吃掉 解法可以直接 getline 兩次,先把前一行的換行吃掉就可以讀下一行了 ```cpp= int x; string y; cin >> x; getline(cin, y); getline(cin, y); ``` ---- ## stringstream #include\<sstream\> 如果字串為一堆數字中間隔一堆空白所組成, e.g. str = "123 52 3 66"; 想把這些數字用陣列存起來,可以使用 stringstream 函式 ```cpp= int arr[10] = {}; string str, tmp; getline(cin, str); stringstream ss(str); for(int i = 0; ss >> tmp; i++){ arr[i] = tmp; } ``` ---- ## 數字中間用逗號隔開的 case input ``` 123,432,542,111 ``` 使用 stringstream 把數字存進陣列中 ```cpp= int arr[10] = {}; char c; string str, tmp; getline(cin, str); stringstream ss(str); ss >> tmp; arr[0] = tmp; for(int i = 0; ss >> c >> tmp; i++){ arr[i] = tmp; } ``` ---- ## 數字與字串之間的轉換 stoi 可以把字串轉換成 int stoll 可以把字串轉換成 long long 型態 to_string 可以把整數轉換成字串 ```cpp= string s = "123"; int x = stoi(s); cout << x << endl; cout << to_string(x) << endl; ``` ---- ## setw #include\<iomanip\> 輸出的格式如果需要靠左/右對齊的題目,可以使用 setw 來輸出 預設是靠右對齊,如果想要靠左對其可以在前面加 left ```cpp= cout << setw(4) << 3 << setw(4) << 12 << endl; cout << setw(4) << 213 << setw(4) << 8 << endl; cout << endl; cout << left << setw(4) << 3 << left << setw(4) << 12 << endl; cout << left << setw(4) << 213 << left << setw(4) << 8 << endl; ``` ![](https://hackmd.io/_uploads/r1wxiVYon.png) ---- ## setfill('0') #include\<iomanip\> setw 預設為靠右,setfill 會把空的位置都補成指定字元 ```cpp= int x = 3; cout << setw(3) << setfill('0') << x << endl;//005 ``` ---- ## setprecision #include\<iomanip\> 控制小數點位數,最後一位會四捨五入 ```cpp= double x = 3.141559; cout << fixed << setprecision(3) << x << endl; cout << fixed << setprecision(4) << x << endl; cout << fixed << setprecision(5) << x << endl; ``` ---- ## ceil/floor/round 控制小數,無條件進位/無條件捨去/四捨五入 至整數 ```cpp= double x = 3.141559; cout << ceil(x) << endl; cout << floor(x) << endl; cout << round(x) << endl; ``` ---- ## 輸出特殊字元 要輸出特殊字元,要再特殊字元前面加反斜線 ```cpp cout << "\\ \' \"" << endl; ``` ---- ## IO 優化 ```cpp ios::sync_with_stdio(0), cin.tie(0); ``` 這個函數是 C++ 為了相容 C,保證程式在使用了 printf 和 std::cout 的時候不發生混亂,將輸出綁到了一起。同步的輸出是安全的。 這其實是 C++ 為了相容而採取的保守措施,也是使 cin/cout 速度較慢的主要原因。我們可以在進行 IO 操作之前將 stdio 解除綁定 但是要注意不能同時使用 std::cin 和 scanf,以及 std::cout 和 printf。 ---- ## 更多語法 [cppreference](https://en.cppreference.com/w/) --- ## 作業 請各位先去 vjudge.net 辦帳號後點以下連結進入群組 [vjudge 群組連結](https://vjudge.net/group/toi--icpc-training?r=wG5DBzKmcopmEWn7sqQn) 之後作業會放在群組內
{"title":"進階輸入輸出","description":"字串輸入","contributors":"[{\"id\":\"19f09ccf-6b99-452f-971f-955cfc1657f3\",\"add\":3578,\"del\":105}]"}
    748 views
   owned this note