Xử lý chuỗi trong C: Toàn tập về string.h và các thao tác cơ bản
Khám phá sức mạnh xử lý chuỗi trong C: thư viện string.h, các hàm quan trọng, và kỹ thuật xử lý văn bản hiệu quả.
•19 tháng 10, 2025

Tóm tắt kiến thức
Chuỗi trong C là nền tảng cho xử lý văn bản và giao tiếp với người dùng. Hiểu rõ cách làm việc với chuỗi, thư viện string.h và các hàm quan trọng sẽ giúp bạn xây dựng các ứng dụng tương tác và xử lý dữ liệu hiệu quả.
Chuỗi (string) trong C thực chất là mảng các ký tự kết thúc bằng ký tự null (\0). Chuỗi là một trong những kiểu dữ liệu quan trọng nhất trong lập trình, được sử dụng để lưu trữ và xử lý văn bản, giao tiếp với người dùng và xử lý dữ liệu.
Quảng cáo giúp chúng tôi duy trì trang web này
Tổng quan về chuỗi
Khái niệm chuỗi
Chuỗi trong C là một mảng các ký tự kết thúc bằng ký tự null (\0). Ký tự null đánh dấu kết thúc chuỗi.
Cú pháp khai báo chuỗi
char tên_chuỗi[kích_thước];Ví dụ thực tế:
#include <stdio.h>
int main() {
char name[50]; // Chuỗi có thể chứa tối đa 49 ký tự
char message[] = "Hello World"; // Khởi tạo với giá trị
char city[20] = "Hanoi"; // Khởi tạo với kích thước cố định
printf("Message: %s\n", message);
printf("City: %s\n", city);
return 0;
}Đặc điểm quan trọng của chuỗi C
- Null terminator: Luôn kết thúc bằng
\0 - Kích thước: Phải cấp phát đủ không gian cho
\0 - Immutable: Chuỗi literal không thể thay đổi
- Array-based: Thực chất là mảng char
Nhập và xuất chuỗi
Xuất chuỗi với printf()
#include <stdio.h>
int main() {
char name[] = "Nguyen Van A";
char message[] = "Xin chao";
printf("Ten: %s\n", name);
printf("Tin nhan: %s\n", message);
return 0;
}Nhập chuỗi với scanf()
#include <stdio.h>
int main() {
char name[50];
char city[30];
printf("Nhap ten: ");
scanf("%s", name); // scanf() dừng khi gặp khoảng trắng
printf("Nhap thanh pho: ");
scanf("%s", city);
printf("Ten: %s\n", name);
printf("Thanh pho: %s\n", city);
return 0;
}Nhập chuỗi có khoảng trắng với gets() và fgets()
#include <stdio.h>
int main() {
char sentence[100];
printf("Nhap cau co khoang trang: ");
fgets(sentence, sizeof(sentence), stdin); // An toàn hơn gets()
printf("Cau vua nhap: %s", sentence);
return 0;
}Các hàm xử lý chuỗi cơ bản
strlen() - Tính độ dài chuỗi
#include <stdio.h>
#include <string.h>
int main() {
char str[] = "Hello World";
int length = strlen(str);
printf("Chuoi: %s\n", str);
printf("Do dai: %d\n", length);
return 0;
}strcpy() - Sao chép chuỗi
#include <stdio.h>
#include <string.h>
int main() {
char source[] = "Hello";
char destination[50];
strcpy(destination, source);
printf("Source: %s\n", source);
printf("Destination: %s\n", destination);
return 0;
}strcat() - Nối chuỗi
#include <stdio.h>
#include <string.h>
int main() {
char str1[50] = "Hello";
char str2[] = " World";
strcat(str1, str2);
printf("Ket qua: %s\n", str1);
return 0;
}strcmp() - So sánh chuỗi
#include <stdio.h>
#include <string.h>
int main() {
char str1[] = "apple";
char str2[] = "banana";
char str3[] = "apple";
int result1 = strcmp(str1, str2);
int result2 = strcmp(str1, str3);
printf("So sanh 'apple' va 'banana': %d\n", result1);
printf("So sanh 'apple' va 'apple': %d\n", result2);
if (result1 < 0) {
printf("'apple' < 'banana'\n");
} else if (result1 > 0) {
printf("'apple' > 'banana'\n");
} else {
printf("'apple' = 'banana'\n");
}
return 0;
}Các hàm xử lý chuỗi nâng cao
strchr() - Tìm ký tự trong chuỗi
#include <stdio.h>
#include <string.h>
int main() {
char str[] = "Hello World";
char *result = strchr(str, 'o');
if (result != NULL) {
printf("Tim thay 'o' tai vi tri: %ld\n", result - str);
printf("Phan chuoi tu vi tri do: %s\n", result);
} else {
printf("Khong tim thay ky tu 'o'\n");
}
return 0;
}strstr() - Tìm chuỗi con
#include <stdio.h>
#include <string.h>
int main() {
char str[] = "Hello World";
char *result = strstr(str, "World");
if (result != NULL) {
printf("Tim thay 'World' tai vi tri: %ld\n", result - str);
printf("Phan chuoi tu vi tri do: %s\n", result);
} else {
printf("Khong tim thay chuoi con 'World'\n");
}
return 0;
}strtok() - Tách chuỗi
#include <stdio.h>
#include <string.h>
int main() {
char str[] = "apple,banana,orange,grape";
char *token;
printf("Chuoi goc: %s\n", str);
printf("Cac phan tu sau khi tach:\n");
token = strtok(str, ",");
while (token != NULL) {
printf("- %s\n", token);
token = strtok(NULL, ",");
}
return 0;
}Xử lý ký tự
Các hàm xử lý ký tự
#include <stdio.h>
#include <ctype.h>
int main() {
char ch = 'A';
printf("Ky tu: %c\n", ch);
printf("La chu hoa: %d\n", isupper(ch));
printf("La chu thuong: %d\n", islower(ch));
printf("La chu cai: %d\n", isalpha(ch));
printf("La so: %d\n", isdigit(ch));
printf("Chuyen thanh chu thuong: %c\n", tolower(ch));
printf("Chuyen thanh chu hoa: %c\n", toupper('a'));
return 0;
}Các thao tác cơ bản với chuỗi
Đảo ngược chuỗi
#include <stdio.h>
#include <string.h>
void reverseString(char str[]) {
int length = strlen(str);
int start = 0;
int end = length - 1;
while (start < end) {
char temp = str[start];
str[start] = str[end];
str[end] = temp;
start++;
end--;
}
}
int main() {
char str[] = "Hello";
printf("Chuoi goc: %s\n", str);
reverseString(str);
printf("Chuoi dao nguoc: %s\n", str);
return 0;
}Đếm số từ trong chuỗi
#include <stdio.h>
#include <string.h>
int countWords(char str[]) {
int count = 0;
int length = strlen(str);
int inWord = 0;
for (int i = 0; i < length; i++) {
if (str[i] != ' ' && str[i] != '\t' && str[i] != '\n') {
if (!inWord) {
count++;
inWord = 1;
}
} else {
inWord = 0;
}
}
return count;
}
int main() {
char sentence[] = "Hello World How Are You";
printf("Cau: %s\n", sentence);
printf("So tu: %d\n", countWords(sentence));
return 0;
}Đếm nguyên âm và phụ âm
#include <stdio.h>
#include <string.h>
#include <ctype.h>
int main() {
char str[] = "Hello World";
int vowels = 0, consonants = 0;
for (int i = 0; i < strlen(str); i++) {
char ch = tolower(str[i]);
if (isalpha(ch)) {
if (ch == 'a' || ch == 'e' || ch == 'i' || ch == 'o' || ch == 'u') {
vowels++;
} else {
consonants++;
}
}
}
printf("Chuoi: %s\n", str);
printf("So nguyen am: %d\n", vowels);
printf("So phu am: %d\n", consonants);
return 0;
}Sắp xếp chuỗi
Sắp xếp mảng chuỗi
#include <stdio.h>
#include <string.h>
void sortStrings(char strings[][50], int n) {
for (int i = 0; i < n - 1; i++) {
for (int j = i + 1; j < n; j++) {
if (strcmp(strings[i], strings[j]) > 0) {
char temp[50];
strcpy(temp, strings[i]);
strcpy(strings[i], strings[j]);
strcpy(strings[j], temp);
}
}
}
}
int main() {
char names[][50] = {"Charlie", "Alice", "Bob", "David"};
int n = sizeof(names) / sizeof(names[0]);
printf("Mang chuoi ban dau:\n");
for (int i = 0; i < n; i++) {
printf("%s\n", names[i]);
}
sortStrings(names, n);
printf("\nMang chuoi sau khi sap xep:\n");
for (int i = 0; i < n; i++) {
printf("%s\n", names[i]);
}
return 0;
}Xử lý chuỗi động
Cấp phát bộ nhớ cho chuỗi
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main() {
char *dynamicString;
int maxLength = 100;
// Cấp phát bộ nhớ
dynamicString = (char*)malloc(maxLength * sizeof(char));
if (dynamicString == NULL) {
printf("Khong the cap phat bo nho!\n");
return 1;
}
printf("Nhap chuoi: ");
fgets(dynamicString, maxLength, stdin);
// Loại bỏ ký tự newline
dynamicString[strcspn(dynamicString, "\n")] = 0;
printf("Chuoi vua nhap: %s\n", dynamicString);
printf("Do dai: %zu\n", strlen(dynamicString));
// Giải phóng bộ nhớ
free(dynamicString);
return 0;
}Ví dụ thực hành
1. Chương trình đăng nhập đơn giản
#include <stdio.h>
#include <string.h>
int main() {
char username[50];
char password[50];
char correctUsername[] = "admin";
char correctPassword[] = "123456";
printf("=== DANG NHAP ===\n");
printf("Ten dang nhap: ");
fgets(username, sizeof(username), stdin);
username[strcspn(username, "\n")] = 0; // Loại bỏ newline
printf("Mat khau: ");
fgets(password, sizeof(password), stdin);
password[strcspn(password, "\n")] = 0; // Loại bỏ newline
if (strcmp(username, correctUsername) == 0 &&
strcmp(password, correctPassword) == 0) {
printf("Dang nhap thanh cong!\n");
} else {
printf("Ten dang nhap hoac mat khau khong dung!\n");
}
return 0;
}2. Chương trình sắp xếp tên theo alphabet
#include <stdio.h>
#include <string.h>
void sortNames(char names[][50], int n) {
for (int i = 0; i < n - 1; i++) {
for (int j = i + 1; j < n; j++) {
if (strcmp(names[i], names[j]) > 0) {
char temp[50];
strcpy(temp, names[i]);
strcpy(names[i], names[j]);
strcpy(names[j], temp);
}
}
}
}
int main() {
char names[][50] = {
"Nguyen Van A",
"Tran Thi B",
"Le Van C",
"Pham Thi D",
"Hoang Van E"
};
int n = sizeof(names) / sizeof(names[0]);
printf("Danh sach ten ban dau:\n");
for (int i = 0; i < n; i++) {
printf("%d. %s\n", i + 1, names[i]);
}
sortNames(names, n);
printf("\nDanh sach ten sau khi sap xep:\n");
for (int i = 0; i < n; i++) {
printf("%d. %s\n", i + 1, names[i]);
}
return 0;
}3. Chương trình đếm tần suất ký tự
#include <stdio.h>
#include <string.h>
int main() {
char str[100];
int frequency[256] = {0}; // Mảng đếm tần suất
printf("Nhap chuoi: ");
fgets(str, sizeof(str), stdin);
str[strcspn(str, "\n")] = 0;
// Đếm tần suất các ký tự
for (int i = 0; i < strlen(str); i++) {
frequency[(unsigned char)str[i]]++;
}
printf("Tan suat cac ky tu:\n");
for (int i = 0; i < 256; i++) {
if (frequency[i] > 0 && i != ' ') {
printf("'%c': %d lan\n", (char)i, frequency[i]);
}
}
return 0;
}Tổng kết
Chuỗi là nền tảng cho việc xử lý văn bản và giao tiếp với người dùng trong C.
Lưu ý quan trọng về chuỗi
- Buffer overflow: Luôn kiểm tra kích thước khi nhập chuỗi
- Null terminator: Không quên ký tự
\0khi thao tác - Memory leak: Giải phóng bộ nhớ khi dùng chuỗi động
- String literals: Không thể thay đổi nội dung chuỗi literal
Best Practices
- Sử dụng
fgets()thay vìscanf()để nhập chuỗi an toàn - Luôn kiểm tra kết quả các hàm xử lý chuỗi
- Sử dụng
strncpy()thay vìstrcpy()để an toàn hơn - Khởi tạo chuỗi trước khi sử dụng
Với những kiến thức này, bạn đã sẵn sàng để xây dựng các ứng dụng tương tác với người dùng và xử lý dữ liệu văn bản phức tạp!
Last updated on
Edit on GitHubThư viện chuẩn C: Khám phá các hàm hữu ích trong stdio.h, string.h, math.h
Khám phá sức mạnh của C Standard Library: stdio.h, stdlib.h, string.h, math.h và các hàm tiện ích quan trọng để viết code hiệu quả.
Struct và Union trong C: Cách tổ chức dữ liệu phức tạp hiệu quả
Khám phá sức mạnh của struct và union trong C: tổ chức dữ liệu có cấu trúc, tối ưu bộ nhớ và xây dựng các kiểu dữ liệu tùy chỉnh.