www.hoasen.edu.vn
Cng Đi hc Hoa Sen xây dng tương lai
Chuỗi (string) và
các bài toán xử lý chuỗi
1
www.hoasen.edu.vn
Cng Đi hc Hoa Sen xây dng tương lai
Người học sẽ đạt được
Trình bày được chuỗi là gì
Trình bày được nguyên tắc kết thúc của chuỗi
Áp dụng được các bài toán thường gặp trong xử lý chuỗi:
Đếm số ký tự trong chuỗi
So sánh 2 chuỗi
Copy chuỗi
Loại bỏ ký tự trong chuỗi
Phân rã chuỗi
2
www.hoasen.edu.vn
Cng Đi hc Hoa Sen xây dng tương lai
Khái niệm về Chuỗi
Khái niệm về Chuỗi
Là mảng một chiều của các ký t (loi char)
Ví dụ:
char hoten[20] = “Nguyen Thi A”;
char ngaysinh[20] = “20/03/1992”;
Ký t trong chuỗi được truy cập như là phần tử của mảng
Hoten[0] = ‘N’; Hoten[1] = ‘g’; Hoten[11] = ‘A’;
ngaysinh[0] = ‘2’; ngaysinh[2] = ‘/’;
3
www.hoasen.edu.vn
Cng Đi hc Hoa Sen xây dng tương lai
Nguyên Tắc Kết Thúc Chuỗi
Nguyên Tắc Kết Thúc Chuỗi
Theo quy ước, chuỗi được kết thúc bằng ký t null hay ‘\0’
Ví dụ: s[] = “abc”;
→ s[0] = ‘a’; s[1] = ‘b’; s[2] = ‘c’; s[3] = ‘\0’;
→ mảng s[] có 4 ký tự
ký t ‘\0’ thường được dng để phát hiện s kết thúc của chuỗi
Lưu ý: ‘a’ và “a” hoàn toàn khác nhau
‘a’ là 1 ký tự
“a” là 1 chuỗi có 2 ký tự ‘a’ và ‘\0’
4
www.hoasen.edu.vn
Cng Đi hc Hoa Sen xây dng tương lai
5
Giả sử khai báo: char S[80];
Nhập chuỗi
scanf(“%s”,&S);
hoặc gets(S);
Xuất chuỗi
printf(S);
printf(“%s”,S);
puts(S);
•
Hàm scanf không nhập chuỗi có khoảng trắng được
•
Để nhập chuỗi có khoảng trắng ta dùng hàm gets
•
Nếu vùng đệm keyboard có dữ liệu thì dữ liệu sẽ chuyển vào biến.
•
Để nhập một chuỗi mới chúng ta phải xoá bộ đệm keyboard bằng hàm fflush(stdin)
Nhập/xuất chuỗi
Nhập/xuất chuỗi
www.hoasen.edu.vn
Cng Đi hc Hoa Sen xây dng tương lai
6
#include<stdio.h>
#include<conio.h>
void main()
{ clrscr();
char S[20];
printf("Nhap chuoi bang ham scanf ");
scanf("%s", &S);
printf("\nChuoi vua nhap: %s", S);
printf("\nNhap chuoi bang ham gets");
gets(S);
printf("\nChuoi vua nhap:");
puts(S);
getch();
}
Nhập/xuất chuỗi
Nhập/xuất chuỗi
puts(S)
tương đương với
printf(“%s\n”,S)
www.hoasen.edu.vn
Cng Đi hc Hoa Sen xây dng tương lai
7
Chuỗi là một mảng các ký t. Vì thế chúng ta có thể truy xuất vào
phần tử ký t của nó bằng chỉ số.
#include<stdio.h>
#include<conio.h>
#include<ctype.h>
void main()
{ clrscr();
char S[20];
printf("Nhap chuoi: ");
gets(S);
int i=0;
while(S[i]!=NULL)
{ S[i] = toupper(S[i]);
i++;
}
printf("Chuoi vua nhap duoc viet hoa:");
puts(S);
getch();
}
Nhập 1 chuỗi
rồi đổi chuỗi
đó ra chữ hoa
Truy xuất từng ký tự của chuỗi
Truy xuất từng ký tự của chuỗi
www.hoasen.edu.vn
Cng Đi hc Hoa Sen xây dng tương lai
8
strlen(s)
Cho biết độ dài của chuỗi s
Ví dụ : n = strlen(“abcd”) n = 4
strcmp(s1, s2)
So sánh chuỗi s1 với s2.
Ví dụ : n = strcmp(s1, s2);
Nếu n > 0 thì s1 > s2
Nếu n = 0 thì s1 = s2
Nếu n < 0 thì s1 < s2
(So sánh dựa vào bảng mã ASCII)
Một số hàm về chuỗi
Một số hàm về chuỗi
www.hoasen.edu.vn
Cng Đi hc Hoa Sen xây dng tương lai
9
strcpy(đích, nguồn)
Chép chuỗi nguồn vào chuỗi đích (gán chuỗi)
Ví dụ : strcpy(ten, “Nguyen Van A”); ten = Nguyen Van A
strcat(s1, s2)
Nối chuỗi s2 vào sau s1.
Ví dụ : s1 = “abcde”; s2 = ”ghk”
strcat(s1, s2) ; s1=abcdeghk
Một số hàm về chuỗi
Một số hàm về chuỗi
www.hoasen.edu.vn
Cng Đi hc Hoa Sen xây dng tương lai
10
toupper(ch)
Đổi ký tự ch thành chữ hoa
isupper(ch)
Kiểm tra ký tự ch có phải là chữ hoa không
tolower(ch)
Đổi ký tự ch thành chữ thường
islower(ch)
Kiểm tra ký tự ch có phải là chữ thường không
Một số hàm về chuỗi
Một số hàm về chuỗi
www.hoasen.edu.vn
Cng Đi hc Hoa Sen xây dng tương lai
VD 1: truy cập ký tự trong chuỗi
Bài toán: nhập tên và xuất tên in ngược
BEGIN
Input: chuỗi tên
Output: chuỗi tên in ngược
1. Nhập chuỗi
2. Xử lý chuỗi:
Loại bỏ ký tự ‘\n’ và ‘\0’ khi nhập chuỗi
Copy chuỗi theo thứ ngược
Thêm ‘\0’ vào cuối chuỗi
3. Xuất chuỗi
END
11
www.hoasen.edu.vn
Cng Đi hc Hoa Sen xây dng tương lai
VD 1: truy cập ký tự trong chuỗi
#include <stdio.h> /* khai báo thư viện cần thiết */
#include <conio.h>
#include <string.h>
#define MAXSTR 100 /* giới hn chiều dài chuổi: 100 ký t */
void main()
{
int i, j;
char name[MAXSTR], opname[MAXSTR];
// 1. nhập chuỗi
printf("\nHi! What is your name: ");
gets(&name);
// 2. xử lý chuỗi: copy ngược các ký t
for(j=0, i=strlen(name)-1; i>=0; i , j++ )
opname[j] = name[i];
opname[j] = '\0‘;
12
www.hoasen.edu.vn
Cng Đi hc Hoa Sen xây dng tương lai
VD 1: truy cập ký tự trong chuỗi
// 3. Xuất chuỗi
printf("Hello, %s. Nice to meet you!\n", name);
printf("Your name in backward: %s\n",opname);
getch();
return 0;
}
13
www.hoasen.edu.vn
Cng Đi hc Hoa Sen xây dng tương lai
VD 2: So sánh chuỗi
Bài toán: tương t chức năng C43 course work
Yêu cầu: Liệt kê tất cả thông tin của khách hàng có tên trong file input.txt.
Input : khachhang.txt, input.txt.
input.txt chứa các chuỗi ký tự là HoTenKH.
Output: output.txt.
14
www.hoasen.edu.vn
Cng Đi hc Hoa Sen xây dng tương lai
VD 2: So sánh chuỗi
Giải thuật:
1. Đọc dữ liệu từ file và nhập vào mảng
1.1 Mở file input.txt, khachhang.txt, output.txt
1.2 Đọc dữ liệu từ file input.txt, khachhang.txt và nhập dữ liệu vào
mảng
1.3 Loại bỏ các khoảng trắng của tên
1.3.1 xóa khoảng trắng khúc đầu của chuỗi
1.3.2 xóa khoảng trắng khúc cuối của chuỗi
1.3.3 thay khoảng trắng giữa các từ bằng 1 ' '
–
So sánh tên
Cho mỗi tên IP trong input.txt
Cho mỗi tên KH trong khachhang.txt
So sánh tên IP và tên KH
»
Nếu giống nhau thì xuất tất cả thông tin KH
»
Còn không xử lý tiếp
15
www.hoasen.edu.vn
Cng Đi hc Hoa Sen xây dng tương lai
VD 2: So sánh chuỗi
#include <stdio.h> /* khai báo thư viện cần thiết */
#include <conio.h>
#include <string.h>
#define MAXSTR 20 /* giới hn chiều dài chuổi: 20
ký t */
#define MAXKH 100 /* giới hn chiều mảng: 100 phần tử */
typedef struct /* struct dữ liệu khách hàng */
{
int maKH;
char soCMND[MAXSTR];
char ngayS[MAXSTR];
char hoten[MAXSTR];
} KH;
void XuLyTen(char s[]); /* hàm xử lý tên khách hàng */
16
www.hoasen.edu.vn
Cng Đi hc Hoa Sen xây dng tương lai
VD 2: So sánh chuỗi
int main()
{
int i, j, soten, soKH;
char name[MAXKH][MAXSTR];
KH kh[MAXKH];
//1.1 mở file
FILE *fkh = fopen("kh.txt","rt");
FILE *fin = fopen("input.txt","rt");
FILE *fout = fopen("output.txt","wt");
if(!fkh || !fin || !fout) /* kiểm tra các file được mở OK */
{ printf("error"); /* nếu không OK thì kết thúc chương
trình */
// fcloseall();
return -1;
}
17
www.hoasen.edu.vn
Cng Đi hc Hoa Sen xây dng tương lai
VD 2: So sánh chuỗi
for(i=0; !feof(fin); i++)
{
fgets(&name[i][0], MAXSTR,fin); // 1.2 Đc dữ liệu từ file vào mảng
XuLyTen(&name[i][0]); // 1.3 Loi bỏ các khoảng trắng của tên
}
soten = i;
for(i=0; !feof(fkh); i++)
{
fscanf(fkh,"%d%s",&kh[i].maKH, ,&kh[i].soCMND);
fscanf(fkh,"%s",&kh[i].ngayS);
fgets(&kh[i].hoten, MAXSTR, fkh); // 1.2 Đc dữ liệu từ file vào mảng
XuLyTen(&kh[i].hoten); // 1.3 Loi bỏ các khoảng trắng của tên
}
soKH = i;
18
www.hoasen.edu.vn
Cng Đi hc Hoa Sen xây dng tương lai
VD 2: So sánh chuỗi
// 2. so sanh ten
for(i=0; i<soten; i++)
for(j=0; j<soKH; j++)
if(strcmp(&name[i][0], kh[j].hoten) == 0) // xuất
tên nếu =
{
fprintf(fout,"%d\t%s\t%s\t%s\n", kh[j].maKH,
kh[j].soCMND, kh[j].ngayS, kh[j].hoten);
break;
}
getch();
return 0;
}
19
www.hoasen.edu.vn
Cng Đi hc Hoa Sen xây dng tương lai
VD 2: So sánh chuỗi
void XuLyTen(char s[])
{
int len=strlen(s);
int i=0, cuoitu;
// 1.3.1 xoa khoang trang khuc dau cua chuoi
while( i < len && (s[i] == '\t’ || s[i] == '\n’ || s[i] == ' ') ) i++;
strcpy(s,&s[i]);
// 1.3.2 xoa khoang trang khuc cuoi cua chuoi
len = len-i;
i=len-1;
while( I >= 0 && (s[i] == '\t‘ || s[i] == '\n‘ || s[i] == ' ') ) i ;
s[i+1] = '\0';
len = i+1;
20
www.hoasen.edu.vn
Cng Đi hc Hoa Sen xây dng tương lai
VD 2: So sánh chuỗi
// 1.3.3 thay khoang trang giua cac tu bang 1 ' '
for( i=0; i<len; i++)
{
while( i < len && s[i] != '\t' && s[i] != '\n' && s[i] !=' ' )
i++;
cuoitu = i;
while( i < len && (s[i] == '\t’ || s[i] == '\n’ || s[i] == ' ') )
i++;
if (i<len) sprintf(&s[cuoitu],"%c%s",' ',&s[i]);
}
}
21
www.hoasen.edu.vn
Cng Đi hc Hoa Sen xây dng tương lai
VD 3: phân rã chuỗi
Bài toán: tương t chức năng C32 course work
Yêu cầu: so sánh tuổi của 2 ngày sinh lưu dạng chuỗi
Input : hai ngày sinh
Output: xuất theo tuổi tăng dần.
Giải thuật:
1.nhập 2 ngày sinh
2.phân rã chuỗi ngày sinh thành 3 chuỗi: ngày, tháng, năm
3.đổi các chuỗi thành số
4.so sánh 2 tuổi và xuất theo tuổi tăng dần
22
www.hoasen.edu.vn
Cng Đi hc Hoa Sen xây dng tương lai
VD 3: phân rã chuỗi
#include <stdio.h>
#include <conio.h>
#include <string.h>
#include <stdlib.h>
#define MAXSTR 20
typedef struct
{
char ngay[3], thang[3], nam[5];
} NS_CHUOI;
typedef struct
{
int ngay, thang, nam;
} NS_SO;
23
www.hoasen.edu.vn
Cng Đi hc Hoa Sen xây dng tương lai
VD 3: phân rã chuỗi
int main()
{
char tuoi_1[] = "10/12/1976"; // 1. nhập 2 ngày
sinh
char tuoi_2[] = "02/09/1976";
char c[] = "/";
char *p;
NS_CHUOI ns_c1, ns_c2;
NS_SO ns_s1, ns_s2;
// 2. phân rã chuỗi ngày sinh thành 3 chuỗi: ngày, tháng, năm
strncpy(ns_c1.ngay,&tuoi_1[0],2); ns_c1.ngay[2] = '\0';
strncpy(ns_c1.thang,&tuoi_1[3],2); ns_c1.thang[2] = '\0';
strncpy(ns_c1.nam,&tuoi_1[6],4); ns_c1.nam[4] = '\0‘;
24
www.hoasen.edu.vn
Cng Đi hc Hoa Sen xây dng tương lai
VD 3: phân rã chuỗi
// 2. phân rã chuỗi ngày sinh thành 3 chuỗi: ngày, tháng, năm: PP
khác
p = strtok(tuoi_2,c);
strcpy(ns_c2.ngay,p);
p = strtok(NULL,c);
strcpy(ns_c2.thang,p);
p = strtok(NULL,c);
strcpy(ns_c2.nam,p);
// 3. đổi các chuỗi thành số
ns_s1.ngay = atoi(ns_c1.ngay);
ns_s1.thang = atoi(ns_c1.thang);
ns_s1.nam = atoi(ns_c1.nam);
ns_s2.ngay = atoi(ns_c2.ngay);
ns_s2.thang = atoi(ns_c2.thang);
ns_s2.nam = atoi(ns_c2.nam);
25