Bài giảng Kỹ thuật lập trình - Bài 4: Chuỗi ký tự - Ngô Hữu Dũng
Bạn đang xem 20 trang mẫu của tài liệu "Bài giảng Kỹ thuật lập trình - Bài 4: Chuỗi ký tự - Ngô Hữu Dũng", để tải tài liệu gốc về máy bạn click vào nút DOWNLOAD ở trên
Tài liệu đính kèm:
- bai_giang_ky_thuat_lap_trinh_bai_4_chuoi_ky_tu_ngo_huu_dung.pdf
Nội dung text: Bài giảng Kỹ thuật lập trình - Bài 4: Chuỗi ký tự - Ngô Hữu Dũng
- Kỹ thuật lập trình Bài 4 – Chuỗi ký tự Ngô Hữu Dũng 91 Kỹ thuật lập trình | DHTH11C | HK1 | 2016-2017 Ngô Hữu Dũng
- Khái niệm Mảng kiểu ký tự char word [] = {'H','e','l','l','o','!'}; Chuỗi ký tự char word [] = {'H','e','l','l','o','!','\0'}; char word [] = "Hello!"; Chuỗi ký tự bao gồm một ký tự đặc biệt nằm cuối chuỗi Báo hiệu kết thúc chuỗi Được hiểu là ký tự NULL, có thể viết là '\0' Một chuỗi, ví dụ "Hello!", đã bao hàm ký tự kết thúc, tức char[7] Kiểu liệt kê, ví dụ {'H','e','l','l','o','!','\0'}, tức char[7] 92 Kỹ thuật lập trình | DHTH11C | HK1 | 2016-2017 Ngô Hữu Dũng
- Khai báo Cú pháp char [ ] = ; Cần xác định kích cỡ của chuỗi Khai báo Khởi tạo một giá trị cho biến cần đủ lớn để chứa có thể lớn hơn chiều dài của bao gồm các ký tự và ký tự NULL (\0) Nếu không khai báo (để trống) Cần khởi tạo chuỗi ban đầu cho biến Kích cỡ của biến chính là chiều dài của chuỗi (gồm ký tự NULL) khởi tạo hợp lệ? nằm giữa dấu hai nháy “” liệt kê {} các ký tự bao gồm ký tự NULL, ‘\0’, ở cuối cùng 93 Kỹ thuật lập trình | DHTH11C | HK1 | 2016-2017 Ngô Hữu Dũng
- Ví dụ khai báo 1. char hello[] = "Hello!"; // char[7] 2. char hi[] = {'H','i','!','\0'}; // char[4] 3. char name[10]; 4. char classname[20] = " Lop tin hoc "; 5. char city[20] = "TP. HCM"; 6. char empty[] = ""; 7. char empty1[10] = ""; 8. char country[] = {'V','N'};// Array, not string! 9. char gender[2] = "male"; // Error!? Overflow 10. char classroom = "V10.4"; // Error!? Char vs string 11. char university[] = 'IUH'; // Error!? Char vs string 12. char a[]; // Error!? unknown size 94 Kỹ thuật lập trình | DHTH11C | HK1 | 2016-2017 Ngô Hữu Dũng
- Khởi tạo giá trị Một khởi tạo giá trị: char hello[] = "Hello!"; Tương đương với char hello[] = {'H','e','l','l','o','!','\0'}; char hello[7] = {'H','e','l','l','o','!','\0'}; char hello[7] = "Hello!"; Một khởi tạo giá trị: char empty[] = ""; Tương đương với char empty[] = {'\0'}; char empty[1] = {'\0'}; char empty[1] = ""; 95 Kỹ thuật lập trình | DHTH11C | HK1 | 2016-2017 Ngô Hữu Dũng
- Khởi tạo giá trị (2) Một khởi tạo giá trị: 0 1 2 3 4 5 6 char hi[7] = "Hi!"; 'H' 'i' '!' '\0' char hi[7] = {'H','i','!','\0'}; Khởi tạo một chuỗi rất dài, dùng dấu \ để xuống dòng char longstring[] = "Toi la sinh vien Cong nghe Thong \ tin\nTruong Dai hoc Cong Nghiep TP. HCM.\n\ Than chao cac ban!"; char longstring[] = "Toi la sinh vien Cong nghe Thong " "tin\nTruong Dai hoc Cong Nghiep TP. HCM.\n" "Than chao cac ban!"; 96 Kỹ thuật lập trình | DHTH11C | HK1 | 2016-2017 Ngô Hữu Dũng
- Phép gán Các phép gán trực tiếp cho chuỗi bị hạn chế Bởi trình biên dịch xử lý với chuỗi như mảng Một khởi tạo giá trị: char hello[] = "Hello!"; Các phép gán trực tiếp sau đó bị trình biên dịch báo lỗi hello = "Good morning!"; // Error! “Good morning!” là const char[14] không gán được cho char[7] hello = "Hi!"; // Error! const char[4] không thể được gán cho char[7] hello = hi; // Error! char[4] không thể được gán cho char[7] 97 Kỹ thuật lập trình | DHTH11C | HK1 | 2016-2017 Ngô Hữu Dũng
- Phép gán (2) Một khai báo char name[10]; name = "Quang"; // Error! const char[6] không gán được cho char[10] name = hello; // Error! char[7] không gán được cho char[10] Làm thế nào để thay đổi giá trị của chuỗi? Dùng các hàm xử lý chuỗi như scanf Thay đổi từng phần tử Các hàm trong thư viện string.h Tự viết hàm xử lý chuỗi ký tự 98 Kỹ thuật lập trình | DHTH11C | HK1 | 2016-2017 Ngô Hữu Dũng
- Nhập chuỗi từ bàn phím Dùng hàm scanf trong thư viện stdio.h scanf("%s",name); Nhập "My name is C", name = "My" scanf("%[^\n]s",name); Nhập "My name is C", name = "My name is C" scanf("%[^e]s",name); Nhập "My name is C", name = "My nam" scanf("%10s",name); Nhập "My_name_is_C", name = "My_name_is" scanf("%s %s",name1, name2); Nhập "My name is C", name1 = "My", name2 = "name" scanf tự động thêm ký tự NULL vào sau chuỗi nhận được từ bàn phím 99 Kỹ thuật lập trình | DHTH11C | HK1 | 2016-2017 Ngô Hữu Dũng
- Phần tử của chuỗi Phép khởi tạo char hello[] = "Hello!"; hello[0] = 'H', hello[1] = 'e', hello[2] = 'l', hello[6] = '\0' Phép gán sau đó hello = "Hi!"; sẽ bị báo lỗi! Có thể thay thế phép gán trên bằng các lệnh: hello[0] = 'H'; hello[1] = 'i'; hello[0] hello[1] hello[2] hello[3] hello[4] hello[5] hello[6] 'H' 'e' 'l' 'l' 'o' '!' '\0' hello[2] = '!'; hello[3] = '\0'; Xuất chuỗi: printf("%s", hello); printf("%s", "e"); // "e"= {'e', '\0'} Xuất ký tự: printf("%c", hello[1]); printf("%c", 'e'); 100 Kỹ thuật lập trình | DHTH11C | HK1 | 2016-2017 Ngô Hữu Dũng
- Thư viện string.h size_t strlen(const char * str) Trả về chiều dài của chuỗi ký tự str strlen(“hello”) = 5, strlen(hello) = 6 size_t: Unsigned integral type const char: Bởi hàm không thay đổi giá trị của str char * strcpy(char * destination, const char * source) Chép nội dung chuỗi source sang chuỗi destination bao gồm ký tự NULL Chuỗi destination phải đủ chứa chuỗi source (bao gồm ký tự NULL) Bản thân hàm trả về destination strcpy(hello, “Hi!”) trả về chuỗi “Hi!” và hello = “Hi!” char * destination: Hàm thay đổi giá trị của destination const char * source: Hàm không thay đổi giá trị của source 101 Kỹ thuật lập trình | DHTH11C | HK1 | 2016-2017 Ngô Hữu Dũng
- Thư viện string.h (2) char * strncpy(char * destination, const char * source, size_t num) Chép num phần tử đầu tiên của source sang destination Nếu num không đủ lớn để bao gồm ký tự NULL của source, hàm không tự gán ký tự NULL vào destination strncpy(hello, “Hi!”, 3); // hello = “Hi!ol!” hello[3]=‘\0’; // hello = “Hi!” strncpy(hello, hi, strlen(hi)+1); // hello = “Hi!” char * strcat( char * destination, const char * source ) Nối chuỗi source vào cuối chuỗi destination destination phải đủ chứa chuỗi kết quả (bao gồm ký tự NULL) char name[10]; strcpy(name, hello); strcat(name, hi); // name = “Hello!Hi!” 102 Kỹ thuật lập trình | DHTH11C | HK1 | 2016-2017 Ngô Hữu Dũng
- Thư viện string.h (3) char * strncat( char * destination, const char * source, size_t num ) Nối num ký tự của chuỗi source vào cuối chuỗi destination Tự động thêm ký tự NULL và chuỗi kết quả (khác với strncpy) strcpy(name, hello); strncat(name, hi, 2); // name = “Hello!Hi” int strcmp( const char * str1, const char * str2 ) So sánh chuỗi str1 với chuỗi str2, so sánh từng ký tự từ đầu đến khi phát hiện điểm khác nhau hoặc đến cuối chuỗi (‘\0’) Giá trị trả về >0: str1 > str2 Giá trị trả về =0: str1 = str2 Giá trị trả về <0: str1 < str2 int strcoll( const char * str1, const char * str2 ) Tương tự strcmp 103 Kỹ thuật lập trình | DHTH11C | HK1 | 2016-2017 Ngô Hữu Dũng
- Thư viện string.h (4) int strncmp ( const char * str1, const char * str2, size_t num ) So sánh num ký tự trong chuỗi str2 với chuỗi str1 const char * strchr( const char * str, int character) Trả về con trỏ (địa chỉ) của vị trí đầu tiên tìm được ký tự character trong chuỗi str printf("%d",strchr(hello,'o')-hello+1); // In ra số 5, tìm thấy ký tự ‘o’ size_t strcspn( const char * str1, const char * str2) Trả về vị trí của phần tử trên str1 giống với ký tự bất kỳ trong str2 printf("%d",strcspn(hello,"I got it!")+1); // In ra số 5, tìm thấy ký tự ‘o’ const char * strpbrk( const char * str1, const char * str2) Giống strcspn nhưng trả về con trỏ (địa chỉ) của ký tự được tìm thấy hoặc NULL nếu không tìm thấy printf("%d",strpbrk(hello,"I got it!")-hello+1); // In ra số 5, tìm thấy ký tự ‘o’ 104 Kỹ thuật lập trình | DHTH11C | HK1 | 2016-2017 Ngô Hữu Dũng
- Thư viện string.h (5) const char * strrchr( const char * str, int character ) Giống strchr nhưng tìm phần từ cuối cùng của chuỗi str printf("%d",strrchr(hello, 'l')-hello+1); // In ra số 4, tìm thấy ký tự ‘l’ sau size_t strspn( const char * str1, const char * str2): Trả về số ký tự đầu tiên trong str1 trùng với bất kỳ ký tự nào trong str2 strspn(hello,hi); // = 1, tìm được chữ ‘H’ strspn(hello, “!olleH”); // = 6, tìm được các chữ H, e, l, l, o, ! strspn(hello, “Heyo!”); // = 2, tìm được các chữ H, e, chữ o không được tính vì không tìm được chữ ‘l’ theo thứ tự const char * strstr( const char * str1, const char * str2 ): Trả về con trỏ (địa chỉ) của vị trí tìm thấy str2 trong str1 printf("%d",strstr(hello,"lo")-hello+1); // = 4 105 Kỹ thuật lập trình | DHTH11C | HK1 | 2016-2017 Ngô Hữu Dũng
- Thư viện string.h (6) char * strtok( char * str, const char * delimiters): Chia chuỗi thành các chuỗi con Char classname[20] = “ Lop tin:11”; printf("%s\n",strtok(classname," :")); // “Lop” printf("%s\n",strtok(NULL," :")); // “Tin” printf("%s\n",strtok(NULL," :")); // “11” void * memset( void * ptr, int value, size_t num): Điền giá trị value vào num bytes ô nhớ đầu tiên của biến ptr memset(hello,'2',2); // hello = “22llo!” void * memcpy( void * destination, const void * source, size_t num ): Chép num ô nhớ đầu tiên của biến source vào biến destination memcpy(hello,hi,3); // hello = “Hi!lo!” 106 Kỹ thuật lập trình | DHTH11C | HK1 | 2016-2017 Ngô Hữu Dũng
- Thư viện string.h (7) void * memmove( void * destination, const void * source, size_t num): Giống memcpy nhưng cho phép chồng lấn memmove(hello,hi,3); // hello = “Hi!lo!” memcpy(hello,hello+3,3); // hello = “lo!lo!” trường hợp chồng lấn int memcmp( const void * ptr1, const void * ptr2, size_t num): So sánh ô nhớ const void * memchr( const void * ptr, int value, size_t num ): Tìm kiếm Ghi chú: Các lệnh về memory (mem) không phân biệt kiểu dữ liệu, chỉ thao tác với dữ liệu binary trong các ô nhớ void * memset( void * ptr, int value, size_t num): Điền giá trị value vào num bytes ô nhớ đầu tiên của biến ptr memset(hello,'2',2); // hello = “22llo!” 107 Kỹ thuật lập trình | DHTH11C | HK1 | 2016-2017 Ngô Hữu Dũng
- Thư viện string.h (8) void * memcpy( void * destination, const void * source, size_t num ) Chép num ô nhớ đầu tiên của biến source vào biến destination memcpy(hello,hi,3); // hello = “Hi!lo!” void * memmove( void * destination, const void * source, size_t num) Giống memcpy nhưng cho phép chồng lấn memmove(hello,hi,3); // hello = “Hi!lo!” memcpy(hello,hello+3,3); // hello = “lo!lo!” trường hợp chồng lấn int memcmp( const void * ptr1, const void * ptr2, size_t num) So sánh num ô nhớ const void * memchr( const void * ptr, int value, size_t num ) Tìm kiếm giá trị value Ghi chú: Các lệnh về memory (mem) không phân biệt kiểu dữ liệu, chỉ thao tác với dữ liệu binary trong các ô nhớ 108 Kỹ thuật lập trình | DHTH11C | HK1 | 2016-2017 Ngô Hữu Dũng
- Chuyển đổi giữa chuỗi và số Thư viện chứa các hàm chuyển đổi giữa chuỗi và số int atoi (const char * str) Chuyển chuỗi str sang số nguyên và trả về giá trị số nguyên atoi("34.5 53") = 34 double atof (const char* str) Chuyển đổi một chuỗi sang kiểu số thực và trả về số thực atof("34.5 53") = 34.5 long int atol ( const char * str ) Chuyển đổi chuỗi sang kiểu long int (4 bytes) long long int atoll ( const char * str ) Chuyển đổi chuỗi sang kiểu long long int (8 bytes) 109 Kỹ thuật lập trình | DHTH11C | HK1 | 2016-2017 Ngô Hữu Dũng
- Chiều dài của chuỗi Chiều dài của chuỗi được xác định dựa vào ký tự NULL, kết thúc chuỗi Viết hàm tính chiều dài của chuỗi Hàm có kiểu nguyên, trả về chiều dài của chuỗi (output) Đối số của hàm là một chuỗi (input) Mã giả: Khai báo một biến đếm và khởi tạo giá trị 0 Duyệt và đếm các phần tử của chuỗi Dừng đếm khi gặp ký tự ‘\0’ Trả về chiều dài của chuỗi dựa vào giá trị của biến đếm Tương tự hàm strlen của thư viện string.h 110 Kỹ thuật lập trình | DHTH11C | HK1 | 2016-2017 Ngô Hữu Dũng
- Ví dụ tham khảo hàm tính chiều dài của chuỗi 1. int stringLength(const char str[]) 2. { 3. int count = 0; 4. while (str[count] != '\0') 5. count++; 6. return count; 7. } 8. 9. int main() 10. { 11. char hello[] = "Hello!"; printf("%d",stringLength(hello)); 12. } 111 Kỹ thuật lập trình | DHTH11C | HK1 | 2016-2017 Ngô Hữu Dũng
- Chép chuỗi Viết hàm chép nội dung của một chuỗi nguồn vào một chuỗi đích Chuỗi đích sẽ mang giá trị của chuỗi nguồn (output) Đối số của hàm là hai chuỗi, nguồn và đích (input) Mã giả Khai báo một biến chạy và khởi gán giá trị ban đầu Duyệt từng phần tử của chuỗi nguồn Gán giá trị của từng phần tử ở chuỗi nguồn sang chuỗi đích Dừng sao chép khi gặp ký tự ‘\0’ Gán ký tự ‘\0’ vào cuối chuỗi đích Tương tự lệnh strcpy của thư viện string.h Hàm có kiểu trả về là void Bạn có thể trả về chuỗi đích cho hàm nếu biết dùng con trỏ, pointer (sẽ học sau) 112 Kỹ thuật lập trình | DHTH11C | HK1 | 2016-2017 Ngô Hữu Dũng
- Ví dụ tham khảo hàm chép chuỗi 1. void stringCopy(char str1[], const char str2[]) 2. { 3. int i=-1; 4. do{ 5. i++; 6. str1[i]=str2[i]; 7. }while (str2[i]!='\0'); 8. } 9. int main() 10. { 11. char hello[10]; 12. stringCopy(hello,"Hello!"); 13. printf("%s",hello); 14. } 113 Kỹ thuật lập trình | DHTH11C | HK1 | 2016-2017 Ngô Hữu Dũng
- Nối chuỗi Viết hàm nối một chuỗi nguồn vào cuối một chuỗi đích Chuỗi đích sẽ mang giá trị là kết quả của việc nối hai chuỗi Đối số của hàm gồm hai chuỗi Mã giả Khai báo hai biến chạy và khởi gán giá trị ban đầu Biến chạy cho chuỗi nguồn, bắt đầu từ đầu chuỗi nguồn Biến chạy cho chuỗi đích, bắt đầu từ cuối chuỗi đích Duyệt từng phần tử của chuỗi nguồn Gán giá trị của các phần tử của chuỗi nguồn vào chuỗi đích Dừng sao chép khi gặp ký tự NULL của chuỗi nguồn Gán ký tự NULL vào chuỗi đích Hàm tương tự như hàm strcpy trong thư viện string.h 114 Kỹ thuật lập trình | DHTH11C | HK1 | 2016-2017 Ngô Hữu Dũng
- Ví dụ tham khảo hàm nối chuỗi 1. void stringAppend(char dest[], const char src[]) 2. { 3. int i = stringLength(dest)-1, j = -1; 4. do{ 5. i++;j++; 6. dest[i]=src[j]; 7. }while(src[j]!='\0'); 8. } 9. int main() 10. { 11. char thanks[20] = "Thank"; 12. stringAppend(thanks, " you!"); 13. printf("%s",thanks); 14. } 115 Kỹ thuật lập trình | DHTH11C | HK1 | 2016-2017 Ngô Hữu Dũng
- So sánh chuỗi Viết hàm so sánh hai chuỗi ký tự str1 và str2 Hàm trả về giá trị 0 nếu str1 > str2 Hàm có 2 đối số là hai chuỗi cần so sánh Mã giả Khai báo và khởi tạo cho một biến chạy Duyệt các phần tử cho đến khi Gặp phần tử khác nhau Hoặc kết thúc một trong hai chuỗi So sánh phần tử cuối cùng và trả về giá trị so sánh tương ứng 116 Kỹ thuật lập trình | DHTH11C | HK1 | 2016-2017 Ngô Hữu Dũng
- Ví dụ tham khảo về hàm so sánh chuỗi 1. int stringCompare(const char str1[], const char str2[]) 2. { 3. int i = 0; 4. while(str1[i]==str2[i]&&str1[i]!='\0'&&str2[i]!='\0') 5. i++; 6. if(str1[i]>str2[i]) 7. return 1; 8. else if (str1[i]<str2[i]) 9. return -1; 10. else 11. return 0; 12. }; 117 Kỹ thuật lập trình | DHTH11C | HK1 | 2016-2017 Ngô Hữu Dũng
- Tìm kiếm Viết hàm tìm kiếm vị trí của một chuỗi nguồn trong chuỗi đích Hàm trả về số nguyên là vị trí đầu tiên tìm thấy Hàm trả về số âm nếu không tìm thấy Đối số của hàm là hai chuỗi Mã giả? ? ? ? ? 118 Kỹ thuật lập trình | DHTH11C | HK1 | 2016-2017 Ngô Hữu Dũng
- Ví dụ tham khảo về tìm kiếm chuỗi Hoạt động?? 1. int stringSearch(const char str1[], const char str2[]) 2. { 3. int i=0, j=0; 4. while(str1[i]!='\0' && str2[j]!='\0') 5. { 6. if(str1[i+j]!=str2[j]) 7. { 8. i++; j=0; 9. } 10. else 11. j++; 12. if (str2[j]=='\0') 13. return i; 14. } 15. return -1; 16. } 119 Kỹ thuật lập trình | DHTH11C | HK1 | 2016-2017 Ngô Hữu Dũng
- Hết bài 4 Khái niệm chuỗi Bài tập về nhà Nhập vào họ và tên, đếm số ký tự alphabet Khai báo, khởi tạo Ví dụ: Nhập “Tran Van An ”, xuất ra có 9 ký tự Nhập vào một chuỗi, đếm số chữ Ví dụ: Nhập “Day la mot chuoi ky tu”, xuất ra có 6 chữ Phần tử của chuỗi Nhập vào họ và tên, xuất ra họ, chữ đệm và tên Ví dụ: Nhập “Tran Van An”, xuất ra họ Tran, chữ đệm Thư viện string.h Van, tên An Nhập vào một số, xuất ra chữ viết của số đó Thư viện stdlib.h Ví dụ: Nhập 456, xuất ra: Bon tram nam muoi sau Một vài bài toán về chuỗi 120 Kỹ thuật lập trình | DHTH11C | HK1 | 2016-2017 Ngô Hữu Dũng