__________________ 思考和讀書都很重要! 阿就是不要只是死讀書啦! 要去想該 function 是怎麼寫的 ? 我們常常推薦使用的 fgets(char* s, int n, FILE* fp) 函數也很值得研究!思考! 這函數(function;函式)其實很單純, 它只是利用 fgetc(FILE* fp) 一直讀 char放入 s, 直到讀到 '\n' 或是已經讀進了 n-1 個 char 就不再讀, 這時不論是因已經讀入 '\n' 或是已經讀了 n-1 個 char 都要補上 '\0' 做為 字串 s 的結束! 還有, 依照 fgets( ) 的手冊, 若啥都沒讀到(遇到 EOF)則回傳 0, 否則須回傳 s 的起始位址。參看 K&R 課本 7.7 節的詳細說明與 fgets( ) 程式碼。 // 以下就是 fgets 這函數的標準寫法 char * fgets(char* s, int n, FILE* fp) { char* p = s; // 就是 p = &s[0]; // p points to s[0]; int c, i = 0; // 注意 c 要宣告成 int 用來讀取一個 char for( ;; ) { c = fgetc(fp); // 請 fgetc 從串流 fp 讀取一字 if(c == -1) break; // -1 是 EOF, 表示已經沒資料可讀了! s[i] = c; // 有讀到就放入 Buffer 中 ++i; // 已經讀了 i 個字, i 剛好指向下一個位置 if( i >= (n-1) ) break; // 至多讀取 n-1 個字 if( c == '\n' ) break; // 已經讀到 NewLine '\n' 也要停 } // for if(i == 0) return 0; // 啥碗糕都沒讀到就遇到EOF, 規定要回傳 0 // 注意, 啥都沒讀到時, 不可把EOF與'\0'填入 s s[i] = 0; // 讓字串結束 return s; // 此例把 s 當 array, 配合s[i] 使用; 所以其實不必複製到 p } // 以下是 fgetc 與 ungetc 的大略版本, 注意不是真正版本! !! // 因為 其實應該要 check 輸入串流 stream, 且這版 ungetc 只可放回一 char, // 但有些新版本 ungetc 可以無限制一直悔棋放回去一個 char 又一個 ...! static int saveFLAG = 0; // 有沒有放回來的字 static int saveChar = 0; // 放回來的字的內碼 int ungetc(int c, FILE*fp) { if(saveFLAG == 1) return -1; // Error! 已經用過 ungetc 但還沒讀走 ! saveFLAG = 1; saveChar = c; // 注意真正版本還要 check fp 喔! return c; } // ungetc( int fgetc(FILE *stream) { static char buf[1024]; // 若要無窮盡 ungetc 則須移到外面變 Global static int i=0, left=0; int k, handle; if(saveFLAG) { // 有放回的字, 先用該字 ! saveFLAG = 0; return saveChar; }// if if(left == 0) { // buf[ ] 沒字了 handle = fileno(stream); // 找出 FILE* stream 的代號 (整數) k=read(handle, buf, 1024); // 至多讀取 1024; read 是 System call if(k < 0) { } // 有 Error, 看要如何處理 ??? if(k == 0) return -1; // EOF 就是 -1, 所以要回傳 -1 表示 EOF left = k; // 讀到 k 個 char i = 0; // i 指向 Buffer 的起點 } left--; // 每次用掉一個 char return buf[i++]; // 注意此處 i++ 不可以寫成 ++i; 意思不同 ! } // fgetc( // ( 註: EOF 就是整數 -1 ) /** 以下抄自TC內打 fgets 敲 Control_F1 後看到的說明 (用 TC++3.0的IDE整合環境) fgets reads characters from stream into the string s. It stops when it reads either n - 1 characters or a newline character, whichever comes first. fgets retains the newline character at the end of s and appends a null byte to s to mark the end of the string. ... Return Value: ■ On success, fgets returns the string pointed to by s. ■ On end-of-file or error, fgets returns null. // 就是 '\0' 也是 0 啦! ***************************************************************************/