Lập trình nâng cao - Bài 9: Xâu

pdf 46 trang vanle 15/06/2021 970
Bạn đang xem 20 trang mẫu của tài liệu "Lập trình nâng cao - Bài 9: Xâu", để 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:

  • pdflap_trinh_nang_cao_bai_9_xau.pdf

Nội dung text: Lập trình nâng cao - Bài 9: Xâu

  1. Bài 9: Xâu Giảng viên: Hoàng Thị Điệp Khoa Công nghệ Thông tin – ĐH Công Nghệ
  2. Chapter 9 Strings Copyright © 2010 Pearson Addison-Wesley. All rights reserved
  3. Mục tiêu bài học • Xâu kí tự kiểu mảng – Kiểu xâu kí tự của C (xâu C) • Các công cụ xử lý kí tự – Đọc/ghi kí tự – Hàm thành viên get, put – putback, peek, ignore • Lớp chuẩn string – Xử lý xâu DTH INT2202
  4. Giới thiệu • Hai kiểu xâu kí tự: 1. Xâu C – Mảng với kiểu cơ sở là char – Đánh dấu kết thúc xâu bằng null, ‘\0’ – Kĩ thuật “cũ” thừa kế từ C 2. Lớp string – Sử dụng khuôn mẫu DTH INT2202
  5. Xâu C • Mảng với kiểu cơ sở là char – Mỗi biến đánh chỉ số là 1 kí tự – Thêm 1 kí tự: ‘\0’ • Gọi là “kí tự null” • Đánh dấu kết thúc xâu • Trong các ví dụ trước ta đã sử dụng xâu C – Hằng giá trị "Hello" được lưu dạng xâu C DTH INT2202
  6. Biến kiểu xâu C • Mảng kí tự: char s[10]; – Khai báo 1 biến kiểu xâu C có thể chứa tối đa 9 kí tự – + 1 kí tự null • Thường là mảng chưa đầy – Khai báo nó đủ lớn để lưu xâu kích thước lớn nhất cần tới – Đánh dấu kết thúc bằng null • Khác biệt duy nhất với mảng chuẩn: – Phải chứa kí tự null DTH INT2202
  7. Việc lưu trữ xâu C • Một mảng chuẩn: char s[10]; – Nếu s chứa xâu kí tự "Hi Mom!", nó được lưu như sau: DTH INT2202
  8. Khởi tạo xâu C • Có thể khởi tạo xâu C: char myMessage[20] = "Hi there."; – Không cần điền đầy toàn bộ mảng – Bước khởi tạo đặt ‘\0’ ở cuối • Có thể bỏ qua kích thước mảng: char shortString[] = "abc"; – Tự động đặt kích thước bằng chiều dài xâu trong ngoặc kép cộng 1 – KHÔNG giống: char shortString[] = {‘a’, ‘b’, ‘c’}; DTH INT2202
  9. Chỉ số trong xâu C • Một xâu C là một mảng • Có thể truy cập tới các biến đánh chỉ số của xâu C. char ourString[5] = "Hi"; – ourString[0] là ‘H’ – ourString[1] là ‘i’ – ourString[2] là ‘\0’ – ourString[3] là không xác định – ourString[4] là không xác định DTH INT2202
  10. Thao tác dựa trên chỉ số của xâu C • Có thể thao tác trên các biến đánh chỉ số char happyString[7] = "DoBeDo"; happyString[6] = ‘Z’; – Hãy cẩn thận! – Ở đây ‘\0’ (null) bị ghi đè bằng ‘Z’! • Nếu null bị ghi đè, xâu C không còn hoạt động như một xâu nữa! – Không lường được kết quả! DTH INT2202
  11. Thư viện • Khai báo xâu C – Không cần thư viện C++ nào cả – Nó có sẵn trong C++ • Các thao tác – Cần thư viện – Thường được khai báo khi dùng xâu C • Khi người viết chương trình muốn làm gì đó trên xâu C DTH INT2202
  12. = và == trên xâu C • Biến kiểu xâu C không giống các biến khác – Không thể gán hay so sánh trực tiếp: char aString[10]; aString = "Hello"; // KHÔNG HỢP LỆ! • Chỉ có thể dùng “=“ khi khai báo kết hợp khởi tạo xâu C! • Phải dùng hàm thư viện cho phép gán: strcpy(aString, "Hello"); – Hàm có sẵn (trong ) – Đặt giá trị của aString bằng "Hello" – Không kiểm tra kích thước! • Người viết chương trình phải kiểm soát. Giống như các thao tác khác trên mảng! DTH INT2202
  13. So sánh các xâu C • Không thể dùng toán tử == char aString[10] = "Hello"; char anotherString[10] = "Goodbye"; – aString == anotherString; // Không được phép! • Phải dùng hàm thư viện: if (strcmp(aString, anotherString)) cout << "Strings NOT same."; else cout << "Strings are same."; DTH INT2202
  14. Thư viện : Display 9.1 Một số hàm trên xâu C có sẵn trong (1/2) • Full of string manipulation functions DTH INT2202
  15. Thư viện : Display 9.1 Một số hàm trên xâu C có sẵn trong (2/2) DTH INT2202
  16. Các hàm trên xâu C: strlen() • “Chiều dài xâu" • Khi làm việc với xâu kí tự ta thường cần thông tin chiều dài xâu: char myString[10] = "dobedo"; cout << strlen(myString); – Trả về số lượng kí tự • Không tính null – Với ví dụ trên: 6 DTH INT2202
  17. Các hàm trên xâu C: strcat() • strcat() • “Nối xâu": char stringVar[20] = "The rain"; strcat(stringVar, "in Spain"); – Kết quả: stringVar chứa "The rainin Spain" – Hãy cẩn thận. Bổ sung dấu cách nếu cần DTH INT2202
  18. Đối số và tham số kiểu xâu C • Nhắc lại: xâu C là mảng • Vì vậy tham số kiểu xâu C là tham số kiểu mảng – Xâu C truyền vào hàm có thể bị hàm biến đổi • Cũng như với mảng, thường thì ta truyền thêm tham số kích thước – Hàm cũng có thể dùng ‘\0’ để tìm điểm kết thúc xâu – Do đó kích thước không thực sự cần thiết nếu hàm không biến đổi xâu – Dùng từ khóa const để bảo vệ đối số kiểu xâu C DTH INT2202
  19. Ghi xâu C • Ta có thể ghi xâu C ra thiết bị xuất (màn hình) dùng toán tử chèn << • Thật ra ta đã làm việc này rồi: cout << news << " Wow.\n"; – Trong đó news là một biến kiểu xâu C • Có thể là do toán tử << đã được nạp chồng cho xâu C! DTH INT2202
  20. Đọc vào xâu C • Có thể đọc dữ liệu từ thiết bị nhập (bàn phím) vào xâu C dùng toán tử trích >> – Tuy nhiên, có vấn đề nảy sinh • Dấu trắng được xem là “kí tự phân cách” (delimiter) – Tab, cách, xuống dòng bị bỏ qua – Việc đọc dừng khi gặp kí tự phân cách • Hãy chú ý kích thước của xâu C • Phải đủ lớn để chứa xâu nhập vào • C++ không cảnh báo về vấn đề này DTH INT2202
  21. Ví dụ đọc vào xâu C • char a[80], b[80]; cout > a >> b; cout << a << b << "END OF OUTPUT\n"; • Kết quả thực thi: Enter input: Do be do to you! DobeEND OF OUTPUT – Lưu ý: phần gạch dưới được nhập từ bàn phím • Xâu C a đọc vào “do” • Xâu C b đọc vào “be” DTH INT2202
  22. Đọc một dòng vào xâu C • Có thể lấy hết dòng kí tự người dùng gõ từ bàn phím vào xâu C • Dùng hàm getline() có sẵn: char a[80]; cout << "Enter input: "; cin.getline(a, 80); cout << a << "END OF OUTPUT\n"; – Kết quả thực thi: Enter input: Do be do to you! Do be do to you!END OF INPUT DTH INT2202
  23. Ví dụ: đối số dòng lệnh • Chương trình được gọi từ dòng lệnh (ví dụ: UNIX shell, nơi nhắc lệnh DOS) có thể nhận đối số – Ví dụ: COPY C:\FOO.TXT D:\FOO2.TXT • Lệnh này chạy chương trình có tên là “COPY” và truyền vào 2 tham số kiểu xâu C “C:\FOO.TXT” và “D:\FOO2.TXT” • Việc xử lý đầu vào diễn ra bên trong chương trình COPY (với ví dụ này là sao tệp có tên chỉ định) • Đối số được truyền vào hàm main dưới dạng mảng các xâu C DTH INT2202
  24. Ví dụ: đối số dòng lệnh • Dòng đầu của main – int main(int argc, char *argv[]) – argc xác định số lượng đối số truyền vào. Nó tính cả tên của chương trình. Do đó argc luôn ≥ 1. – argv là một mảng các xâu C. • argv[0] lưu tên của chương trình được gọi • argv[1] lưu tham số thứ nhất • argv[2] lưu tham số thứ hai • v.v. DTH INT2202
  25. Example: Command Line Arguments // Test.cpp // In ra màn hình các đối số truyền qua dòng lệnh int main(int argc, char* argv[]){ for(int i = 0; i Test hello world trình lần 1 Gọi chương trình Test từ nơi Doi so 0: Test > Test nhắc lệnh Doi so 1: hello Doi so 0: Test Doi so 2: world DTH INT2202
  26. Bàn thêm về getline() • Có thể chỉ định tường minh kích thước đọc vào: char shortString[5]; cout << "Enter input: "; cin.getline(shortString, 5); cout << shortString << "END OF OUTPUT\n"; – Kết quả thực thi: Enter input: dobedowap dobeEND OF OUTPUT – Bắt buộc chỉ đọc vào 4 kí tự • Kí tự cuối là null được bổ sung tự động DTH INT2202
  27. Đọc/ghi kí tự • Dữ liệu đọc vào và ghi ra – Tất cả đều được xử lý dạng kí tự – Ví dụ: số 10 ghi ra là ‘1’ và ‘0’ – Việc chuyển đổi được thực hiện tự động • Dùng các tiện ích bậc thấp • Ta c ũng có thể dùng các tiện ích bậc thấp này DTH INT2202
  28. Hàm thành viên get() • Đọc từng kí tự một • Hàm thành viên của đối tượng cin: char nextSymbol; cin.get(nextSymbol); – Đọc kí tự tiếp theo và đưa vào biến nextSymbol – Đối số phải có kiểu char • Không thể là xâu DTH INT2202
  29. Hàm thành viên put() • Ghi từng kí tự một ra thiết bị xuất • Hàm thành viên của đối tượng cout: cout.put(‘a’); – In chữ cái ‘a’ ra màn hình char myString[10] = "Hello"; cout.put(myString[1]); – In chữ cái ‘e’ ra màn hình DTH INT2202
  30. Các hàm thành viên khác • putback() – Sau khi lấy dữ liệu từ luồng vào biến, có thể ta cần trả nó lại cho luồng – cin.putback(lastChar); • peek() – Trả về kí tự tiếp theo trong luồng, nhưng vẫn để nó lại luồng – peekChar = cin.peek(); • ignore() – Bỏ qua luồng nhập tới khi nào gặp kí tự chỉ định – cin.ignore(1000, ‘\n’); • Bỏ qua tối đa 1000 kí tự tới khi gặp ‘\n’ DTH INT2202
  31. Ví dụ: Chương trình dùng hàm putback // Nguồn: // istream putback #include using namespace std; int main(){ char c; int n; char str[256]; cout = '0') && (c > n; cout > str; cout << "Ban da nhap vao tu " << str << endl; } cin.ignore(80, '\n'); cin.get(); return 0; } DTH INT2202
  32. Các hàm thao tác với kí tự: Display 9.3 Một số hàm trong (1/3) DTH INT2202
  33. Các hàm thao tác với kí tự: Display 9.3 Một số hàm trong (2/3) DTH INT2202
  34. Các hàm thao tác với kí tự: Display 9.3 Một số hàm trong (3/3) DTH INT2202
  35. Lớp chuẩn string • Đã định nghĩa trong thư viện: #include using namespace std; • Biến và biểu thức string – Xử lý như với các kiểu đơn • Có thể gán, so sánh, cộng: string s1, s2, s3; s3 = s1 + s2; // Nối s3 = "Hello Mom!" // Gán – Lưu ý là xâu C "Hello Mom!" được chuyển tự động sang kiểu string! DTH INT2202
  36. Display 9.4 Chương trình dùng lớp string DTH INT2202
  37. Đọc/ghi với lớp string • Giống như các kiểu khác! • string s1, s2; cin >> s1; cin >> s2; • Kết quả thực thi: Người dùng gõ vào: May the hair on your toes grow long and curly! • Toán tử trích bỏ qua dấu trắng: s1 đọc vào giá trị "May" s2 đọc vào giá trị "the" DTH INT2202
  38. getline() với lớp string • Để đọc hết dòng người dùng gõ vào: string line; cout << "Enter a line of input: "; getline(cin, line); cout << line << "END OF OUTPUT"; • Kết quả thực thi: Enter a line of input: Do be do to you! Do be do to you!END OF INPUT – Tương tự như cách dùng getline() cho xâu C DTH INT2202
  39. Phiên bản getline() khác • Có thể chỉ định kí tự phân cách: string line; cout > s2; – Cho kết quả là: (cin) >> s2; DTH INT2202
  40. Lỗi thường gặp: Kết hợp các phương pháp đọc • Hãy cẩn thận khi kết hợp cin >> var với getline – int n; string line; cin >> n; getline(cin, line); – Nếu nhập vào:42 Hello hitchhiker. • Biến n sẽ được đặt bằng 42 • line đặt bằng xâu rỗng! – cin >> n bỏ qua dấu trắng, để ‘\n’ lại trong luồng cho getline()! DTH INT2202
  41. Xử lý xâu với lớp string • Có các phép toán như cho xâu C • Và hơn thế nữa! – Hơn 100 thành viên của lớp string chuẩn • Một số hàm thành viên: – .length() • Trả về độ dài của biến string – .at(i) • Trả về tham chiếu tới kí tự ở vị trí i DTH INT2202
  42. Display 9.7 Hàm thành viên của lớp string chuẩn (1/2) DTH INT2202
  43. Display 9.7 Hàm thành viên của lớp string chuẩn (1/2) DTH INT2202
  44. Chuyển đổi giữa xâu C và đối tượng string • Chuyển đổi kiểu tự động – Từ xâu C thành đối tượng string: char aCString[] = "My C-string"; string stringVar; stringVar = aCstring; • Hoàn toàn hợp lệ và đúng! – aCString = stringVar; • Không hợp lệ! • Không thể tự động chuyển thành xâu C – Phải dùng lệnh chuyển đổi tường minh: strcpy(aCString, stringVar.c_str()); DTH INT2202
  45. Tóm tắt • Biến kiểu xâu C là “mảng kí tự” – Với kí tự null (‘\0’) bổ sung ở cuối • Xâu C hoạt động như mảng – Không thể gán, so sánh như các biến đơn • Các thư viện & có nhiều hàm xử lý giúp xử lý xâu dễ dàng • cin.get() đọc kí tự tiếp theo trong luồng • getline() đọc hết 1 dòng trong luồng • Thao tác với đối tượng string tiện lợi hơn xâu C DTH INT2202
  46. Chuẩn bị bài tới • Đọc chương 10 giáo trình: Con trỏ và Mảng động DTH INT2202