Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> การเขียนโปรแกรม >> C++

cin.ignore() ใน C++: ล้าง Input Buffer ป้องกันข้าม Input

std::cin.ignore() ใช้สำหรับ ข้าม (Discard) ตัวอักษรใน Input Buffer ป้องกันปัญหา "ข้าม Input" ที่พบบ่อยเมื่อผสมใช้ operator>> (Formatted Input) กับ getline() (Unformatted Input)

ปัญหา: ทำไม Input ถูกข้าม?


int x;
char str[80];
std::cin >> x;        // อ่านตัวเลข, ทิ้ง '\n' ไว้ใน Buffer
std::cin.getline(str, 80); // อ่าน '\n' ที่เหลือ -> ได้ Empty String ทันที!

operator>> อ่าน Token แล้วหยุดที่ Whitespace (Space, Tab, Newline) ทิ้ง Delimiter ไว้ใน Buffer getline() อ่านจนกว่าจะเจอ Newline -> เจอทันที -> คืน Empty String

แก้ไขด้วย cin.ignore()


#include <iostream>
#include <limits>     // numeric_limits
#include <ios>        // streamsize

int main() {
    int x;
    char str[80];
    
    std::cout << "Enter number and string:\n";
    std::cin >> x;
    
    // ล้าง Buffer จนกว่าจะเจอ Newline (รวม Newline ด้วย)
    std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
    
    std::cin.getline(str, 80); // อ่านบรรทัดเต็มได้ปกติ
    
    std::cout << "Number: " << x << "\nString: " << str << '\n';
}

ผลลัพธ์


Enter number and string:
42
Hello World
Number: 42
String: Hello World

ignore() Overloads


// 1. Ignore 1 Character (Default)
cin.ignore(); 

// 2. Ignore n Characters
cin.ignore(n); 

// 3. Ignore n Characters หรือจนกว่าเจอ Delim (มาตรฐาน)
cin.ignore(n, delim); // n = streamsize max = "ไม่จำกัด"

Best Practice Pattern


// หลังจาก >> ทุกครั้งที่จะตามด้วย getline/get
std::cin >> value;
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); // Clear Line

// หรือ Helper Function
void clearInputBuffer() {
    std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
}

ข้อระวัง

  • ignore() ไม่ Block หาก Buffer ว่าง (Non-blocking)
  • หาก Stream ใน Error State (failbit, badbit) ต้อง cin.clear() ก่อน
  • ใช้ std::ws Manipulator กับ getline ได้: std::getline(std::cin >> std::ws, str); (Skip Leading Whitespace)

สรุป

cin.ignore(numeric_limits<streamsize>::max(), '\n') เป็น Idiom มาตรฐานสำหรับล้าง Input Buffer หลัง operator>> ก่อนใช้ getline() ป้องกัน Bug "ข้าม Input" ได้อย่างมีประสิทธิภาพ