170 likes | 310 Views
String and character functions. #include <string.h> #include <ctype.h>. ASCII table. int a; (char)a 取 lower byte of a. char ach; (int)ach ascii number of ach. (int)space = 32 = 0x20 (int)’0’ = 48 = 0x30, (int)’9’ = 57 = 0x39 (int)’A’ = 65 = 0x41, (int)’Z’= 90 = 0x5a
E N D
String and character functions #include <string.h> #include <ctype.h>
ASCII table • int a; (char)a 取lower byte of a. • char ach; (int)ach ascii number of ach. • (int)space = 32 = 0x20 • (int)’0’ = 48 = 0x30, (int)’9’ = 57 = 0x39 • (int)’A’ = 65 = 0x41, (int)’Z’= 90 = 0x5a • (int)’a’ = 97 = 0x61, (int)’z’ = 122 = 0x7a
Character testing • #include <ctype.h> • int isalpha(int a); // among a-z or A-Z? • int isdigit(int a); // among 0-9? • int ispunct(int a); • int isupper(int a); // is a upper-case letter? • int islower(int a); // is a low-case letter? • int tolower(int a); // change to lower-case? • int toupper(int a); //change to upper-case?
Memory copy • include <string.h> • memset(void*pt, int char, unsigned count); e.g. memset(str, NULL, 1024U) • memmove(void*to, void*from, unsigned ncount) • memcmp(void*p1, void*p2, unsigned count)
strncpy(str*s1, str*s2, unsigned count); unsigned int strlen(char *str); • strlen(char*str); //回傳字串長度 • strncpy: • 從 s2 複製 count 個字元到 s1. • 如果 count > s2 的長度, 則複製 strlen(s2) • 若 count < strlen(s2), s1沒有終止字元. • int strncmp(str1, str2, count); example
字串複製和比較 • strcpy(char*to, char*from); • int strcmp(char*str1, char*str2); (相同時回傳 0)
char* strchr(char*str, int ach); • 在 str 字串中尋找第一個 (char)ach 的字元, 回傳該字元的位址. 若沒吻合的則回傳 NULL. • char* strrchr(char*str, int ach); 與 strchr 類似, 但找最後一個.
char* strpbrk(char*str1, char*str2) • 在 str1 字串中尋找第一個字元, 與 str2 中任一字元相同者. • 回傳該字元的位址. • 若失敗, 則傳回 NULL. • int strspn(char*str1, char*str2) 第一個 substring 的長度, 不包含 str2 所有的字元. • char*strtok(char*str1,char*str2) 尋找下一個符和標誌 – str1 被改變.
char*strstr(char*str1, char*str2) • 在 str1 字串中, 尋找和 str2 字串一樣的位置. • 回傳吻合 str2 的第一個位址. 若無吻合者,回傳 NULL
練習八、搜尋字串 • 用 gen_db.c產生一個 data 檔 makeup.db. • 寫一個程式 display makeup.db 的資料, 並有下列功能: • 顯示指定的第 n 筆資料. • 顯示 indicator 以下的 10 筆資料 • 顯示 indicator 之前的 10 筆資料 • 更改 indicator 所在的那一筆資料成積. • 搜尋 name 中含有給與的特定字串之資料. • 搜尋 idno 中含有給與的特定字串之資料.
main() 的結構 • 打開 makeup.db in “rb+” mode. • Count the number of total record, maxrec. • Set current record ncur = 0 (ncur 紀錄目前的 record number). • Read in the first record, and reset the indicator to beginning of fp. • 顯示動作選單, 並 prompt for 字元輸入 a. • 清理 input buffer: fflush(stdin); • Read from stdin, a char action, and change it to upper case. • Act according to ‘action’. (switch action). • Case ‘Q’: close files, and return. • Case ‘D’: display the current record, then break. • Case ‘P’: display 10 records from the current indicator, and • set indicator at the beginning of the 10th record. ncur = ncur+9. • Case ‘B’: display 10 record backward, and set the indicator • at the beginning of the last record. Break; ncur = ncur – 9. • Case ‘N’: input (from stdin) a string, and search in the name of • all records for that string. Break; ncur move to the first found record. • Case ‘I’: input a string, and search it in the idno of all records. Ncur = first found • Case ‘C’: display current record, and prompt for input of new • t1, t2, and t3, then redo average, rewrite this record • in fp. Break; • Default: 顯示輸入錯誤選擇, break; • 7. 重覆 3-4. 用 while(1) 將步驟 1-6 括起來.
Function declaration void move_fp(FILE *fp, int n, int rlen): move to the beginning of nth record. STUDENT read_record(FILE*fp, int rlen) read the current record. 注意: 本程式中最好不要在 read_record 中改變 fp 的指標位置. STUDENT write_record(FILE*fp, STUDENT ss, int rlen) : wirte ss into the current record. 更改 :回傳 ss 來 update main 中的 current record. int search(FILE*fp, char *str, int nind): seach sting str[] in the filed name or idno and return the number of first found. void display_record(STUDENT ss): display struct ss to monitor.
Search string(FILE*fp, char*str) • 計算 record 長度 rlen • 計算 record 總數 maxrec (這兩個參數也可以用幅數輸入) • Set indicator to the beginning of fp • For loop i=0, maxrec-1 • 讀取 current record ss; • Copy 要搜尋的字串 (名字或學號) strcpy(nstr1, ss.name); • 統一字串的大小寫. • Test nstr1 內有無 str: strstr(nstr1, str) != NULL • 若有: sn++; 列印 record. 若 sn==1 紀錄此一 record 的號碼到 n1 • e. End of for loop. • f. 列印發現 match 的總數. • g. 回傳 n1 (第一個發現的 record). • 回主程式, ncur = 回傳的號碼. • 更新主程式中的 current record, ss, 重置 fp 的指標到 ncur 的起點
Write record • ** make sure 指標位置是在寫位置的開始點 (若正確應該如此). • Display current record, and prompt for input t1, t2, t3. • Input tt.t1, tt.t2, tt.t3 • 計算 tt.avg • Set str = (char*)(&tt) • fwrite(str, rlen, 1, fp) : 寫入一筆長度為 rlen 的資料 • 再 set 指標回該筆資料的起始位置 fseek(fp, (-rlen), 1); • 將 ss 回傳主程式, 更新主程式中的 current record. • 在主程式中 顯示更新後的 current record.
統一字串到小寫 #include<string.h> #include <ctype.h> void stolower(char *str) { int k; for (k=0; k<strlen(str); k++) str[k] = tolower(str[k]); retrun; } int strlen(str) : 回傳 str 字串的長度, 開始一直到 \0 tolower(achr) : 將字元 achr 轉為小寫 (對非字母沒有作用)