510 likes | 686 Vues
Input/Ouput. Chap 22. 22.1 Streams. Stream means any source of input or any destination for output . A file pointer is used to access a stream. FILE *fp1, *fp2; Standard streams. Opening a File (22.2). Syntax: FILE *filePtr = fopen(fileName, mode);
E N D
Input/Ouput Chap 22
22.1 Streams • Stream means any source of input or any destination for output. • A file pointer is used to access a stream. FILE *fp1, *fp2; • Standard streams
Opening a File (22.2) • Syntax: FILE *filePtr = fopen(fileName, mode); • filePtr is a variable of a file pointer, a pointer to a FILE-structure object. • mode: read (讀檔), write (寫檔), append (追加);text (文字檔), binary 檔. (See next page) • Ex: FILE *fptr = fopen("mydata.txt", "r");
Opening a File • mode in fopen(): • "r": • If the file does not exit, file opening fails; • Otherwise open it. • "w": • If the file exists, current content will be discarded; • If the directory in the file name does not exist,file opening fails; • Otherwise, create a new file for writing.
Opening a File • Table of file open modes (開啟模式):
Opening a File • ASCII mode (純文字模式): • fopen()預設是 ASCII 模式 • 讀入 DOS 換行符號 "\r\n" (\x0d0a)時,會自動改成 '\n' • 寫出 '\n'時也會改為 "\r\n" • '\0'會被視為字串結尾 • Binary mode: • 在 fopen()中以 "rb", "wb", etc. 開啟檔案 • 影片檔、圖片檔、甚至 MSWord檔都應該以 binary 格式存取。
Opening a File • fopen() • On failure, fopen()returns NULL. • It is a good habit to check if the return value is NULL whenever you open a file. • Ex:FILE *fptr = fopen("mydata.txt", "r");if (fptr == NULL){ printf("開檔失敗\n"); exit(0);}
Closing a File (22.2) • Syntax:fclose(FILE * filePtr); • Ex:FILE *fptr = fopen("mydata.txt", "r");// handling files here, then...fclose(fptr); • fclose()returns memory allocated for this file pointer • If you open too many files without closing it, your program will crash.
Checking end-of-file (22.2) • Syntax:feof(FILE * filePtr); • Returns true if the end-of-file indicator of the stream for this file pointer is set.
22.5 Line I/O • fgets(char *str, int size, FILE *fptr) • Read in one line from a file. • If end-of-file is found, returns NULL. • Ex:FILE *fptr = fopen("mydata.txt", "r");char buf[1000];while (fgets(buf, sizeof(buf), fptr)!= NULL){// buf 是新讀入的一行文字 } • fputs(const char *str, FILE *fptr) • Write a line into a file.
22.3 Formatted I/O • fscanf(FILE *fptr, …scanf-params… ) • Same format and usage as scanf(), but its first parameter is a FILE pointer and the input comes from this file. • fprintf(FILE *fptr, …printf-params…) • Same format and usage as printf(), but its first parameter is a FILE pointer and the output is stored in this file.
Formatted Input/Output Section 22.3
printf() • printf(format string, other arguments); • Format specification: • %[flags] [width] [.precision] [{h | l | I64 | L}]type • Ex: printf( "%+3.5lf", 4.56);
Printing Integers (整數) • 負數會印出負號來 一般 八進位制 unsigned 十六進制 長短整數
Printing Floating-Point Numbers(浮點數) • %f – 印浮點數, 小數點前至少一位, 小數點後六位 • %e, %E – 科學記號表示法 Exponential notation (computer's version of scientific notation) • 150.3 的科學記號表示法是 1.503 x 10² • 電腦改以 1.503E+002 表示 (E 表 exponent) • 可規定大小寫 e or E • %g (or %G) – 選 %f or %e (%E), 後面不補零 (1.2300 只印出 1.23) • 選 %e: 指數小於 -4, 或大於等於precision (預設6位) • 選 %f: 其他情形
Printing Strings and Characters • %c: 字元 character • %s: 字串 string • 請注意 • 字元以一對 single quotes 表示 ('z') • 字串以一對 double quotes 表示 ("z")
Other Conversion Specifiers • %p • 印出位址格式 • %% • 印出百分比號 (%) 回 printf
Field Widths 欄位寬度 • 設定欄寬所用 • 預設是靠右對齊 • 如果資料超過欄寬,仍會全部印出 Ex.for (i = 8; i < number; i++) printf("%3d %d\n", i, score[i]); 8 31 9 77 10 82 11 62 回 printf 寬度=3
Precisions • Format • 設定在句點 (.) 之後 • 意義看各個 data type • 整數:最少印出幾個數字 • 數字太小的話,前面補零 • 浮點數: • %f, %e: 小數點後有幾位數字 • %g: significant digits最多位數 • 字串:最多印出幾個字元
Examples printf("%.3d\n", score[i]); 301 023 2134 printf("%.3f\n", value[i]); 3.010 23.000 2.135 printf("%.6s\n", monthName[i]); Januar Fabrua March
Examples printf("%.5e\n", score[i]); 3.40000e-003 3.40000e-005 3.45678e-005 printf("%.5g\n", score[i]); 0.0034 3.4e-005 3.4568e-005
Field Widths and Precisions • Field width and precision可同時指定 • Ex. %5.3f • field width 或 precision 的值想用變數來指定時,用星號 asterisk (*) • Example:printf( "%*.*f", 7, 2, 98.736 ); %7.2f 回 printf
Flags • 加在%後面 • 有些 flags 可以組合使用
Examples printf("%8s%d\n", monthName[i], i+1); January1 Fabruary2 March3 printf("%-8s%d\n", monthName[i], i+1); January 1 Fabruary2 March 3 printf("%-8s%+d\n", monthName[i], i+1); January +1 Fabruary+2 March +3
Examples printf("%d\n", number[i]); 85 -85 printf("% d\n", number[i]); 85 -85 printf("%06d\n", score[i]); 000085 000100
Examples printf("%o, %#o\n", 1487, 1487); 2717, 02717 printf("%x, %#x\n", 1487, 1487); 5cf, 0x5cf printf("%X, %#X\n", 1487); 5CF, 0X5CF
scanf() • scanf(format string, other arguments); • Format specification: • %[*] [width] [{h | l | I64 | L}]type • Ex: scanf( "%3d", &name);
Formatting Input with scanf • Table continued from previous slide 回 scanf
scanf() • 讀到不屬於指定型態所用的字元時就會停止 scanf("%x",&number); printf("您輸入了 %x,就是 %d\n", number, number); 234afternoon (←自己輸入) 您輸入了 234af,就是 144559 scanf("%d",&number); printf("您輸入了 %d\n", number); 234afternoon (←自己輸入) 您輸入了 234
Field Width in scanf() • 最多只讀幾個字元,從中找出資料
Examples scanf("%d", &number); printf("您輸入了%d\n", number); 123456 (←自己輸入) 您輸入了123456 • Field width in scanf() Ex. scanf("%2d%d", &a, &b); printf("您輸入了 %d 和 %d\n", a, b); 123456 (←自己輸入) 您輸入了 12 和 3456
Example scanf("%c%s", &ch, str); printf("您輸入了 %c 和 %s\n", ch, str); String definition (←自己輸入) 您輸入了 S 和 tring
Formatting Input with scanf • %[ ]: Scan sets • 只讀入在 scan set 裡的字元 • 讀到不在 scan set 中的字元時就停止 • %[^ ]: Inverted scan sets • 只讀入不在 scan set 裡的字元 • 讀到在 scan set 中的字元時就停止
Examples scanf("%[abcde]",str); printf("您輸入的字串是 %s\n",str); baby (←自己輸入) 您輸入的字串是 bab scanf("%[abcde ]",str); printf("您輸入的字串是 %s\n",str); babe cat (←自己輸入) 您輸入的字串是 babe ca
Examples scanf("%[^abcde]",str); printf("您輸入的字串是 %s\n",str); lover (←自己輸入) 您輸入的字串是 lov
Formatting Input with scanf • Skipping characters • 所有其他出現在 format specification 中的字元都是在輸入時要被跳過的字元 • 或用 * 來跳過任何字元
Example • scanf("%d/%d/%d", &y, &m, &d);printf("您輸入了%d年%d月%d日\n",y,m,d); • 必須以此格式輸入 • 99/2/15 • 否則找完第一個數後就因格式不合而結束動作 99/2/15 (←自己輸入) 您輸入了99年2月15日 99-2-15 (←自己輸入) 您輸入了99年-858993460月-858993460日
Example • scanf("%d/%d/%d",&y,&m,&d); 可接受輸入格式 • 99/2/15 • scanf("%d%*c%d%*c%d",&y,&m,&d); 可接受輸入格式 • 99/2/15 • 99-2-15 • 99.2&15 __
Examples scanf("%d%*c%d",&m,&d); printf("%d 月 %d 日\n",m,d); //跳過任意一個字元 12_5 (←自己輸入) 12 月 5 日 scanf("%d%*d%d",&m,&d); printf("%d 月 %d 日\n",m,d); //跳過任意一個整數 12 23423 5 (←自己輸入) 12 月 5 日
Examples scanf("%d%*s%d",&m,&d); printf("%d 月 %d 日\n",m,d); //跳過任意一個字串 12and... 5! (←自己輸入) 12 月 5 日
Practice • 輸入格式為 yyyymmdd • 如何讀出年月日? • 輸入 "Peter is a student"或 "Mary is an operator" • 將第一個字串存入 name (名字),第四個字串存入 occup (職業)
22.6 Block I/O • Reading or writing a block of data into a file at one time. • fread() • fwrite() • Especially useful for handling binary files
Block I/O fread(const void *buffer, size_t size, size_t count, FILE *fptr) Reading data from a file into a buffer. count: number of data; size: size of each datum Ex: int a[30], k; FILE *fptr; ... // 讀一筆整數資料到一個整數變數 fread(&k, sizeof(int), 1, fptr); // 一次讀30 筆整數資料到一個整數陣列 fread(a, sizeof(int), 30, fptr);
範例 int k; FILE *fptr; ... fread(&k, sizeof(int), 1, fptr); // k 的值就會變成 (00 00 01 02)2=258 // 注意x86 機器儲存 bytes 的順序是 low byte 在前面,high byte 在後面 fptr 所開檔案 02 01 00 00 a1 00 00 00 00 00 8C 45 00 77 EF DD .......................
Block I/O fwrite(const void *buffer, size_t size, size_t count, FILE *fptr) Write data into a file. count: number of data; size: size of each datum Ex:int a[30], k; FILE *fptr; ... // 將一個整數變數資料寫到檔案 fwrite(&k, sizeof(int), 1, fptr); // 一次將30 筆陣列中的整數資料寫到檔案 fwrite(a, sizeof(int), 30, fptr);
22.8 String I/O • sscanf(char *str, …scanf-params… ) • Same format and usage as scanf(), but its first parameter is a string and the input comes from this string. • sprintf(char *str, …printf-params…) • Same format and usage as printf(), but its first parameter is a character array and the output is stored in the array as a string.
22.4 Character I/O • fgetc(FILE *fptr) • Read in one chatacter from a file. • You should check end of file by yourself by usingfeof(). • fgetc(stdin) equals getchar() • fputc(int ch,FILE *fptr) • Write a character into a file. • fputc('a',stdout) equals putchar('a')
22.7 File Positioning • fseek(FILE *fptr, int offset, seek_const ) • 將檔案讀取位置移至指定位置 seek_const可設為 • SEEK_SET –移至檔頭算來 offset 的位置 • SEEK_CUR –移至目前位置再往後 offset 的位置 • SEEK_END –移至檔尾算來 offset 的位置 • offset 單位是 bytes,offset<0 表往回的相對位置 • rewind( FILE *fptr ) • 將檔案讀取位置歸零 • int ftell( FILE *fptr ) • 傳回目前檔案讀取位置