fgets() – An toàn, khuyến khích
Đọc dòng từ stream vào buffer, tối đa n-1 ký tự, dừng tại newline hoặc EOF. Giữ lại \n nếu còn chỗ. Tự thêm \0. Kiểm tra bounds -> an toàn. Khai báo trong <stdio.h>.
char *fgets(char *str, int n, FILE *stream);
Ví dụ
#include <stdio.h>
#define SIZE 8
int main() {
char buf[SIZE];
fgets(buf, SIZE, stdin);
printf("Doc duoc: %s", buf);
return 0;
}
Nhập: Hello World! (12 ký tự)
Kết quả
Doc duoc: Hello W
Chỉ đọc 7 ký tự + null = 8 (SIZE). Phần còn lại ở lại trong stdin.
gets() – Nguy hiểm, ĐÃ LOẠI BỎ (C11)
Đọc dòng từ stdin, không kiểm tra kích thước buffer -> buffer overflow dễ dàng. Không an toàn. Đã bị xóa khỏi chuẩn C11.
char *gets(char *str);
Ví dụ (chỉ để hiểu)
#include <stdio.h>
#include <string.h>
int main() {
char s[100];
printf("Nhap chuoi: ");
gets(s); // KHONG BAO GIO DUNG TRONG CODE THAT
for (int i = 0; s[i]; i++)
if (s[i] >= 'a' && s[i] <= 'z')
s[i] -= 32; // Lower to upper
printf("Chuoi in hoa: %s", s);
return 0;
}
Kết quả
Nhap chuoi: hello world!
Chuoi in hoa: HELLO WORLD!
Bảng so sánh
| Đặc điểm | fgets() | gets() |
|---|---|---|
| Kiểm tra bounds | Có (n-1) | Không |
| Giữ newline | Có (nếu vừa) | Không (thay bằng \0) |
| Stream | Tuỳ chọn (stdin/file) | Chỉ stdin |
| An toàn | Có | Không (deprecated/removed) |
| Chuẩn | C89+ | C89, removed C11 |
CẤM TUYỆT ĐỐI: Không bao giờ dùng
gets(). Luôn dùng fgets() hoặc C++ std::getline.