cin.ignore() dùng để bỏ qua (loại bỏ) ký tự trong bộ đệm nhập (input buffer). Rất quan trọng khi kết hợp operator>> (đọc format) với getline() (đọc dòng).
Vấn đề thường gặp
#include <iostream>
int main() {
int x;
char str[80];
std::cout << "Nhap so va chuoi:\n";
std::cin >> x; // Đọc số, để lại '\n' trong buffer
std::cin.getline(str, 80); // Đọc dòng - NHẬN '\n' CÒN LẠI → DÒNG RỖNG
std::cout << "So: " << x << "\nChuoi: '" << str << "'\n";
}
Kết quả lỗi
Nhap so va chuoi: 42 So: 42 Chuoi: '' (rỗng!)
Giải pháp: cin.ignore()
#include <iostream>
#include <limits> // numeric_limits
#include <ios> // streamsize
int main() {
int x;
char str[80];
std::cout << "Nhap so va chuoi:\n";
std::cin >> x;
// Xóa buffer đến hết dòng (kể cả '\n')
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
std::cin.getline(str, 80);
std::cout << "So: " << x << "\nChuoi: '" << str << "'\n";
}
Kết quả đúng
Nhap so va chuoi: 42 Hello World So: 42 Chuoi: 'Hello World'
Các dạng cin.ignore()
| Cú pháp | Hành vi |
|---|---|
cin.ignore() | Bỏ qua 1 ký tự |
cin.ignore(n) | Bỏ qua tối đa n ký tự |
cin.ignore(n, delim) | Bỏ qua tối đa n ký tự, dừng khi gặp delim (kể cả delim) |
Pattern phổ biến
// Xóa toàn bộ buffer đến newline
cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
// Hoặc helper function
void clear_input_buffer() {
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
}
Khi nào cần ignore()?
- Sau
cin >> int/double/chartrướcgetline() - Sau khi đọc ký tự đơn lẻ
cin >> ch(còn lại '\n') - Xử lý input lỗi:
cin.clear(); cin.ignore(...);
Xử lý input lỗi (Error recovery)
int x;
while (true) {
std::cout << "Nhap so: ";
if (std::cin >> x) break; // Thành công
// Thất bại: xóa lỗi + xóa buffer
std::cin.clear(); // Reset failbit
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
std::cout << "Khong hop le, thu lai.\n";
}
Tóm tắt
operator>>để lại delimiter (thường là '\n') trong buffergetline()đọc đến delimiter và lấy nó ra (nhưng không lưu)- Luôn
cin.ignore()sau>>trướcgetline() - Dùng
numeric_limits<streamsize>::max()để xóa toàn bộ dòng