Tài liệu 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
Ngô Hữu DũngKỹ thuật lập trình | DHTH11C | HK1 | 2016-201791
Khái niệm
Ngô Hữu DũngKỹ thuật lập trình | DHTH11C | HK1 | 2016-201792
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]
Khai báo
Ngô Hữu DũngKỹ thuật lập trình | DHTH11C | HK1 | 2016-201793
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 ...
30 trang |
Chia sẻ: putihuynh11 | Lượt xem: 630 | Lượt tải: 0
Bạn đang xem trước 20 trang mẫu tài liệu 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
Kỹ thuật lập trình
Bài 4 – Chuỗi ký tự
Ngô Hữu Dũng
Ngô Hữu DũngKỹ thuật lập trình | DHTH11C | HK1 | 2016-201791
Khái niệm
Ngô Hữu DũngKỹ thuật lập trình | DHTH11C | HK1 | 2016-201792
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]
Khai báo
Ngô Hữu DũngKỹ thuật lập trình | DHTH11C | HK1 | 2016-201793
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
Ví dụ khai báo
Ngô Hữu DũngKỹ thuật lập trình | DHTH11C | HK1 | 2016-201794
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
Khởi tạo giá trị
Ngô Hữu DũngKỹ thuật lập trình | DHTH11C | HK1 | 2016-201795
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] = "";
Khởi tạo giá trị (2)
Ngô Hữu DũngKỹ thuật lập trình | DHTH11C | HK1 | 2016-201796
Một khởi tạo giá trị:
char hi[7] = "Hi!";
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!";
0 1 2 3 4 5 6
'H' 'i' '!' '\0'
Phép gán
Ngô Hữu DũngKỹ thuật lập trình | DHTH11C | HK1 | 2016-201797
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]
Phép gán (2)
Ngô Hữu DũngKỹ thuật lập trình | DHTH11C | HK1 | 2016-201798
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ự
Nhập chuỗi từ bàn phím
Ngô Hữu DũngKỹ thuật lập trình | DHTH11C | HK1 | 2016-201799
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
Phần tử của chuỗi
Ngô Hữu DũngKỹ thuật lập trình | DHTH11C | HK1 | 2016-2017100
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[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');
hello[0] hello[1] hello[2] hello[3] hello[4] hello[5] hello[6]
'H' 'e' 'l' 'l' 'o' '!' '\0'
Thư viện string.h
Ngô Hữu DũngKỹ thuật lập trình | DHTH11C | HK1 | 2016-2017101
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
Thư viện string.h (2)
Ngô Hữu DũngKỹ thuật lập trình | DHTH11C | HK1 | 2016-2017102
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!”
Thư viện string.h (3)
Ngô Hữu DũngKỹ thuật lập trình | DHTH11C | HK1 | 2016-2017103
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
Thư viện string.h (4)
Ngô Hữu DũngKỹ thuật lập trình | DHTH11C | HK1 | 2016-2017104
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’
Thư viện string.h (5)
Ngô Hữu DũngKỹ thuật lập trình | DHTH11C | HK1 | 2016-2017105
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
Thư viện string.h (6)
Ngô Hữu DũngKỹ thuật lập trình | DHTH11C | HK1 | 2016-2017106
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!”
Thư viện string.h (7)
Ngô Hữu DũngKỹ thuật lập trình | DHTH11C | HK1 | 2016-2017107
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!”
Thư viện string.h (8)
Ngô Hữu DũngKỹ thuật lập trình | DHTH11C | HK1 | 2016-2017108
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ớ
Chuyển đổi giữa chuỗi và số
Ngô Hữu DũngKỹ thuật lập trình | DHTH11C | HK1 | 2016-2017109
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)
Chiều dài của chuỗi
Ngô Hữu DũngKỹ thuật lập trình | DHTH11C | HK1 | 2016-2017110
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
Ví dụ tham khảo hàm tính chiều dài của chuỗi
Ngô Hữu DũngKỹ thuật lập trình | DHTH11C | HK1 | 2016-2017111
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. }
Chép chuỗi
Ngô Hữu DũngKỹ thuật lập trình | DHTH11C | HK1 | 2016-2017112
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)
Ví dụ tham khảo hàm chép chuỗi
Ngô Hữu DũngKỹ thuật lập trình | DHTH11C | HK1 | 2016-2017113
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. }
Nối chuỗi
Ngô Hữu DũngKỹ thuật lập trình | DHTH11C | HK1 | 2016-2017114
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
Ví dụ tham khảo hàm nối chuỗi
Ngô Hữu DũngKỹ thuật lập trình | DHTH11C | HK1 | 2016-2017115
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. }
So sánh chuỗi
Ngô Hữu DũngKỹ thuật lập trình | DHTH11C | HK1 | 2016-2017116
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
= 0 nếu str1 = str2
> 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
Ví dụ tham khảo về hàm so sánh chuỗi
Ngô Hữu DũngKỹ thuật lập trình | DHTH11C | HK1 | 2016-2017117
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. };
Tìm kiếm
Ngô Hữu DũngKỹ thuật lập trình | DHTH11C | HK1 | 2016-2017118
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ả?
?
?
?
?
Ví dụ tham khảo về tìm kiếm chuỗi
Ngô Hữu DũngKỹ thuật lập trình | DHTH11C | HK1 | 2016-2017119
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. }
Hết bài 4
Ngô Hữu DũngKỹ thuật lập trình | DHTH11C | HK1 | 2016-2017120
Khái niệm chuỗi
Khai báo, khởi tạo
Phần tử của chuỗi
Thư viện string.h
Thư viện stdlib.h
Một vài bài toán về chuỗi
Bài tập về nhà
Nhập vào họ và tên, đếm số ký tự alphabet
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ữ
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
Van, tên An
Nhập vào một số, xuất ra chữ viết của số đó
Ví dụ: Nhập 456, xuất ra: Bon tram nam muoi sau
Các file đính kèm theo tài liệu này:
- bai_giang_ky_thuat_lap_trinh_ts_ngo_huu_dung_ky_thuat_lap_trinh_ngo_huu_dung_bai_04_9936_1985329.pdf