取自C++編程思想的源碼require.h 一些小的內聯函數
1: #ifndef REQUIRE_H
2: #define REQUIRE_H
3: #include <cstdio>
4: #include <cstdlib>
5: #include <fstream>
6:
7: inline void require(bool requirement,
8: const char* msg = "Requirement failed") {
9: using namespace std;
10: if (!requirement) {
11: fputs(msg, stderr);
12: fputs("\n", stderr);
13: exit(1);
14: }
15: }
16:
17: inline void requireArgs(int argc, int args,
18: const char* msg = "Must use %d arguments") {
19: using namespace std;
20: if (argc != args + 1) {
21: fprintf(stderr, msg, args);
22: fputs("\n", stderr);
23: exit(1);
24: }
25: }
26:
27: inline void requireMinArgs(int argc, int minArgs,
28: const char* msg =
29: "Must use at least %d arguments") {
30: using namespace std;
31: if(argc < minArgs + 1) {
32: fprintf(stderr, msg, minArgs);
33: fputs("\n", stderr);
34: exit(1);
35: }
36: }
37:
38: inline void assure(std::ifstream& in,
39: const char* filename = "") {
40: using namespace std;
41: if(!in) {
42: fprintf(stderr,
43: "Could not open file %s\n", filename);
44: exit(1);
45: }
46: }
47:
48: inline void assure(std::ofstream& in,
49: const char* filename = "") {
50: using namespace std;
51: if(!in) {
52: fprintf(stderr,
53: "Could not open file %s\n", filename);
54: exit(1);
55: }
56: }
每次創建ifstream和ofstream都會有assure()函數來確保文件成功打開。
get()或者讀取sz-1個字符或者遇到文件為’\n’然後在buf尾部加0終結符。get()會把文件內遇到終結符留在輸入流中,所以需要使用get()將終結符扔掉。也可以使用ignore()函數來做這個事情,第一個參數是要扔掉的字符數,默認為1,第二個參數是要扔掉的字符,默認是EOF。
getline()函數自動把輸入流中的’\n’取消掉了。所以下次可以直接讀取輸入流中的數據,一般使用geiline().
get和getline都在讀取後在buf的尾部加了一個字符串結尾終結符‘0’。
1: #include "../require.h"
2: #include <fstream>
3: #include <iostream>
4: using namespace std;
5:
6: int main() {
7: const int sz = 100; // Buffer size;
8: char buf[sz];
9: {
10: ifstream in("Strfile.cpp"); // Read
11: assure(in, "Strfile.cpp"); // Verify open
12: ofstream out("Strfile.out"); // Write
13: assure(out, "Strfile.out");
14: int i = 1; // Line counter
15:
16: // A less-convenient approach for line input:
17: while(in.get(buf, sz)) { // Leaves \n in input
18: in.get(); // Throw away next character (\n)
19: cout << buf << endl; // Must add \n
20: // File output just like standard I/O:
21: out << i++ << ": " << buf << endl;
22: }
23: } // Destructors close in & out
24:
25: ifstream in("Strfile.out");
26: assure(in, "Strfile.out");
27: // More convenient line input:
28: while(in.getline(buf, sz)) { // Removes \n
29: char* cp = buf;
30: while(*cp != ':')
31: cp++;
32: cp += 2; // Past ": "
33: cout << cp << endl; // Must still add \n
34: }
35: } ///:~
get讀取一個字符
cin.get(ss,80); 查輸入流緩沖區,看到'\n'符時,從輸入流緩沖區一個字符一個字符地讀取字符,讀入不超過79個字符,並轉換為整型值,存入ss.
保持'\n'符在輸入流中,不清除它。
cin.getline(ss,80); 查輸入流緩沖區,看到'\n'符時,從輸入流緩沖區一次讀入一行字符,作為字符串,存入ss, 清除輸入流中的這個'\n'符,存入ss的字符串中也不包括這個'\n'符。
istream& get (char* s, streamsize n ); 使用說明中指出,何時應當用getline,不用 get 。 你的情況就是不能用 get 啊。
cin.getline()和cin.get()都是對輸入的面向行的讀取,即一次讀取整行而不是單個數字或字符,但是二者有一定的區別。
cin.get()每次讀取一整行並把由Enter鍵生成的換行符留在輸入隊列中,比如:
#include <iostream>
using std::cin;
using std::cout;
const int SIZE = 15;
int main( ){
cout << "Enter your name:";
char name[SIZE];
cin.get(name,SIZE);
cout << "name:" << name;
cout << "\nEnter your address:";
char address[SIZE];
cin.get(address,SIZE);
cout << "address:" << address;
}
輸出:
Enter your name:jimmyi shi
name:jimmyi shi
Enter your address:address:
在這個例子中,cin.get()將輸入的名字讀取到了name中,並將由Enter生成的換行符'\n'留在了輸入隊列(即輸入緩沖區)中,因此下一次的cin.get()便在緩沖區中發現了'\n'並把它讀取了,最後造成第二次的無法對地址的輸入並讀取。解決之道是在第一次調用完cin.get()以後再調用一次cin.get()把'\n'符給讀取了,可以組合式地寫為cin.get(name,SIZE).get();。
cin.getline()每次讀取一整行並把由Enter鍵生成的換行符拋棄,如:
#include <iostream>
using std::cin;
using std::cout;
const int SIZE = 15;
int main( ){
cout << "Enter your name:";
char name[SIZE];
cin.getline(name,SIZE);
cout << "name:" << name;
cout << "\nEnter your address:";
char address[SIZE];
cin.get(address,SIZE);
cout << "address:" << address;
}
輸出:
Enter your name:jimmyi shi
name:jimmyi shi
Enter your address:YN QJ
address:YN QJ
由於由Enter生成的換行符被拋棄了,所以不會影響下一次cin.get()對地址的讀取。...余下全文>>