Chuỗi ký tự trong C

Leave a Comment

Chuỗi ký tự trong C

Khái niêm :

Là mảng 1 chiều gồm các phần tử có kiểu char như mẫu tự, con số và bất cứ ký tự đặc biệt như +, -, *, /, $, #… 
•Viết trong cặp nháy kép, ví dụ: "I like C++"
–Theo quy ước, một xâu sẽđược kết thúc bởi ký tự null ('\0' : kí tựrỗng). 
–Xâu là một con trỏ (pointer) trỏ đến ký tự đầu tiên của xâu (giống như với mảng)
Ví dụ: xâu s="Infoworld";được lưu trữ như sau:


Trong đó con trỏ s trỏ đến ký tựđầu tiên 'I' 
Kết thúc bằng nul lnhư vậy rất khác so với các ngôn ngữ khác. Ví dụ, trong Pascal, mỗi chuỗi kí tự bao gồm một mảng kí tự và length byte chứa chiều dài chuỗi. Cấu trúc này giúp Pascal dễ dàng trả về độ dài chuỗi khi được yêu cầu. Khi đó, Pascal chỉ việc trả về giá trị  length byte, trong khi C phải đếm cho tới khi nó gặp kí tự '\0'. Đây là lí do khiến C chậm hơn Pascal trong một vài tình huống nhất định

1.Gán giá trị cho xâu (string assignment)


• Mảng của ký tự:
char color[] = "blue"; 
Biến con trỏ char* 
char*colorPtr = "blue";
tạo con trỏ colorPtr trỏ đến chữ b trong xâu "blue" ("blue" ởtrong bảng chuỗi hằng)
• Khởi tạo chuỗi như mảng:
char color[] = { 'b', 'l', 'u', 'e', '\0' };
Cần phải nhắc nhở bạn rằng việc gán nhiều hằng như việc sử dụng dấu ngoặc kép (") chỉ hợp lệ khi khởi tạo mảng, 
tức là lúc khai báo mảng. Các biểu thức trong chương trình như sau là không hợp lệ: 

mystring = "Hello";
mystring[] = "Hello";
mystring = { 'H' , 'e', 'l', 'l', 'o',  ' \0' };
Chúng ta chỉ có thể "gán" nhiều hằng cho một mảng v ào lúc khởi tạo nó. Nguyên nhân là mộtthao tác gán (=) không thể nhận vế trái là cả một mảng mà chỉ có thể nhận một trong những phần tử của nó. Vào thời điểm khởi tạo mảng là một trường hợp đặc biệt, vì nó không thực sự là một lệnh gán mặc dù nó sử dụng dấu (=).
Tuy nhiên C++ cho phép ta gán 2 mảng tĩnh có cùng kích thước như sau:
chara[]="Hello", b[6];
//hello và ký tự null tổng cộng 6 ký tự
//khai báo như trên thì 2 mảng tĩnh có cùng kích thước
b=a;
Phép gán này tương đương đoạn chương trình sau:
int i=0; 
while ( a[i] <= 6 ) 
b[i]=a[i++];
Thiết lập n ký tự đầu của xâu s bằng kýtự c bằng 1 trong 2 hàm sau:
voidstrnset( chars[], charc, intn): 
void memset(char *Des, intc, size_tn);

2.Những chuỗi hằng

Bạn hãy thử hai đoạn chương trình sau:
char *s="hello";    
cout<< s;
và:
chars[100]; 
strcpy( s,"hello");    
cout<< s; 
Hai đọan mã trên đưa ra cùng một kết qủa, nhưng cách họat động của chúng hòan tòan khác nhau. Trong đọan 2, bạn không thể viết s=”hello”;. Để hiểu sự khác nhau, bạn cần phải biết họat động của bảng chuỗi hằng(string constant table) trong C.
Khi chương trình được thực thi, trình biên dịch tạo ra một file object, chứa mã máy và một bảng chứa tất cả các chuỗi hằng khai báo trong chương trình. Trong  đọan 1, lệnh  s  =  ”hello”;xác định rằng  s chỉ đến địa chỉ của chuỗi  hello trong bảng chuỗi hằng. Bởi vì chuỗi này nằm trong bảng chuỗi hằng, và là một bộ phận trong mã exe, nên bạn không thể thay đổi được nó. Bạn chỉ có thể dùng nó theo kiểu chỉ-đọc (read-only).Để minh họa, bạn có thể chèn thêm câu 
lệnh strcpy(s,"modify"); vào sau lệnh gán ở ví dụ 1, trình biên dich sẽ báo lỗi ghi vào hằng.
Trong đọan 2, chuỗi hello cũng tồn tại trong bảng chuỗi hằng, do đó bạn có thể copy nó vào mảng kí tự tên là s. Bởi vì s không phải là một con trỏ, lệnh s=”hello”;sẽ không làm việc.

Sẽ đề cập trong phần con trỏ.

3.Đọc chuỗi 


• Đọc dữ liệu cho mảng ký tự:
char word[20];
cin >>word;

-Đọc xâu không chấp nhận khoảng trống.
-Xâu có thể vượt quá kích thước mảng.

cin >>setw( 20 ) >>word; // đọc 19 ký tự (1 để dành cho '\0')

Đọc xâu với khoảng trống dùng 1 trong các cú pháp sau:

gets(array);//trong stdio.h, không được khuyến khích sử dụng 
cin.get(array);
cin.get(array,size);
cin.getline(array,delimiter='\n' );
//ký tự delimiter mac dinh la ' \n' -xuong dong
cin.getline(array, size, delimiter=' \n');

–Lưu input vào mảng array đến khi xảy ra một trong hai trường hợp 
+ Kích thước dữ liệu đạt đến size –1
+ Ký tự delimiter được nhập vào
Lưu ý :delimiter='\n' th ìdấu = làtham số mặc định trong C++, tức là nếu không có tham số này thì trình biên dịch sẽ hiểu là để mặc định
Ví dụ:
charsentence[ 80 ];
cin.getline(sentence, 80);
//dung delimiter mac dinh

Đối với các hàm get hay getline ta hoàn toàn có thể kết hợp với toán tử >> như thế này:
cout << " Nhap ten,tuoi, nghe nghiep" << endl ;
//cin.ignore();
cin.getline( name )>> age >>job;

Nếu một chương trình bị treo hay kết thúc bất thường khi làm việc với xâu thường là do một số ký tự vẫn còn trong vùng đệm. Kết quả là chương trình có vẻ kết thúc sớm hơn mong muốn.
Hàm fflush() hay cin.ignore() sẽ giải quyết vấn đề này. Nó sẽ làm sạch vùng đệm và chép tất cả những gì có trong vùng đệm ra ngoài( trong ví dụ ở trên thì nó không thật sự cần thiết lắm )

Bài trước : Kiểu ký tự char 

0 nhận xét:

Đăng nhận xét