170 likes | 304 Views
I/O FUNCTIONS. 輸入 與 輸出. #include <stdio.h>. int fclose(FILE *); int feof(FILE *); int fflush(FILE *); int fgetc(FILE *); getchar(); char *fgets(char*, int, FILE*); gets(char*); FILE *fopen(char*, char*); int fprintf(FILE*, char*,…); printf(char*,…);
E N D
I/O FUNCTIONS 輸入 與 輸出
#include <stdio.h> • int fclose(FILE *); • int feof(FILE *); • int fflush(FILE *); • int fgetc(FILE *); getchar(); • char *fgets(char*, int, FILE*); gets(char*); • FILE *fopen(char*, char*); • int fprintf(FILE*, char*,…); printf(char*,…); • int fputc(int, FILE*); putchar(int); • int fputs(char*, FILE*); puts(char*); • int fscanf(FILE*, char*, …); scanf(); sscanf();
fseek(FILE*fp, long offset, int origin) fread(char*str,int size, int count, FILE*fp) fwrite(char*str, int size, int count, FILE *fp) long ftell(FILE*fp) void rewind(FILE*fp) int remove(char*fname) int rename(char*oldname, char*newname)
Write to or read from a string • sprintf(str, format, variables) 與 printf 相同, 但是輸出的目標是寫 到字串上, 而非 monitor. • sscanf(str, format, variables) 與 scanf 相同, 但是從一個字串上讀取變數資料
先讀一列資料到 str, 在從 str 中讀取變數值 FILE *fp; char str[80], name[10]; float r1, r2, r3; fp = fopen(“fname.txt”, “r”) fgets(str, (int)80, fp); sscanf(str,”%s %f %f %f”,name, &r1, &r2, &r3); fgets(char*str, int n, FILE*fp) :從 fp 中讀取 n 個 bytes, 直到斷行或 end_of_file
Binary files– No text convertion FILE *fp; fp = fopen(file_name_str, mode_str); Mode_str “rb”: an existing binary file for read “wb”: a new binary file for write “rb+”: an existing binary file for read/write “wb+”: a new binary file for read/write 用途: 執行檔, 隨意讀取的data base 檔, 暫存檔
Conversion from unix-tex to dos-text (example) fp1 = fopen(argv[1],"rb") fp2 = fopen(argv[2],"wb"); nc = counter = 0; while (!feof(fp1)) { achr = fgetc(fp1); if (achr == 255 ) break; if (achr == 10) { fputc((int)13, fp2); nc++; } fputc((int)achr, fp2); counter++; }
Store text data in binary mode typedef struct { int nd; char id[12], name[8]; float t1, t2, t3, avg; } STUDENT; void write_one_record(FILE *fp, STUDENT ss) { char *str; int rlen; rlen = sizeof(ss); str = (char*)&ss; fwrite(str, rlen, (int)1, fp); return; } example
ss.nd ss.id ss.t1 ss.name ss.t2 ss.t3 ss,avg fwrite(str, size, count, fp) char *str: 字串位址 int size: 要寫入的 byte 數 int count: 重複數次 FILE fp: 寫入檔案 sizeof(STUDENT) = 40 char *str; str = (char*)&ss; fwrite(str, 40, 1 fp);
Display contents of a data-base file STUDENT read_one_record(FILE *fp) { STUDENT ss; //回傳的資料 int rlen; char *str; str = (char*)&ss; //把str指向儲存位址 rlen = sizeof(ss); //record 長度 fread(str, rlen,(int)1, fp); // 讀取 data 到 str 指向的位址. return(ss); } // 回傳以後, ss 就可以按一般的 struct 處理. example
移動 file indicator 的位置 fseek(FIlE *fp, long int offset, int refer) offset: 相對移動的 byte 數目 refer: 參考點, 0 以 beginning 為參考點 SEEK_SET 1 以目前為參考點 SEEK_CUR 2 以 end_of_file 為參考點 SEEK_END fseek 可以移動超過 end_of_file 但不能在 biginning of file 之前
練習 2.1 • Open binary file student.db (mode “rb”) • STUDENT 的結構: { int nd; char id[12], name[8]; float t1, t2, t3, avg; } 3. 計算總 record 數目 totaln. 4. 等 user 輸入一個數目 n, 若 n < 0 or n > totaln 結束. 5. 若 n >= 0, 則讀取並 display 第 n+1 個學生資料. 5. 重複 3-4 的步驟.
Counting total number of record rlen = sizeof(STUDENT); fseek(fp, (long)0, SEEK_END); totaln = (int)(ftell(fp)/rlen));
fseek(fp, bytes_to_seek, origin) 將 fp 的 indicator 移動到指定的 bytes 數, 移動以 origin 為計算起點: Origin = 0, 以檔案 fp 的起始點作為原點SEEK_SET Origin = 1, 以目前的 indicator 起始點作為原點 SEEK_CUR Origin = 2, 以檔案 fp 的最後作為原點 SEEK_END Moving to the end of file: fseek(fp, 0, SEEK_END);
long int ftell(fp) ftell(fp) 回傳一個 long int 為目前 indicator 的位置. 在 text mode 下, ftell 所傳回的數目意義難測, 但可以儲存下來, 給 fseek 用來回到某一特定位置.
int fread(address, size, count, fp); fread 從目前的 indicator開始讀取 size 個 byte 的 data, 存到 address 所指定的位置. 這種讀取重覆 count 次. 讀完之後, fp 的 indicator 移動到讀完的下一個位置. fread 回傳讀入的 byte 數, 當讀數較少時, 可能碰到 eof.
fwrite(address, size, count, fp); fwrite 從 address 的位置讀取 size 個 byte 的 data, 寫入 indiactor 所的位置. 這種動作重覆 count 次. 寫完之後, fp 的 indicator 移動到的下一個位置. fwrite 回傳實際寫入的 byte 數.