Sunday, 8 January 2012

C Programming - fflush function and output stream!

Ai đã từng lập trình C hẳn rất quen thuộc với hàm fflush. Nhưng các bạn thường hiểu nhầm công dụng của nó.
fflush là hàm "chỉ" dùng để xóa bộ đệm dòng ra(output stream), khi sử dụng với dòng vào(input stream) thì sẽ gây ra sự vận hành không xác định của các chương trình(behave undefine). Nhưng thường thì chúng ta lại dùng để xóa dòng vào chuẩn(stdin) với suy nghĩ loại bỏ những thứ không mong đợi được đưa vào từ bàn phím khi chạy chương trình.

vd: fflush(stdin); fgets(name); đó là một sai lầm rất ngớ ngẩn vì đơn giản fflush không dùng cho các dòng vào và có thể gây ra những lỗi không ngờ tới.
Để giải thích công dụng của fflush mình xin đưa ra một đoạn code đơn giản sau:
Trường hợp 1:
#include "stdio.h"
#include "stdlib.h"

int main(void)
{
int i;
for(i = 0;i < 10; i++)
{
printf("%d", i);
sleep(1);
}
return 0;
}

Trường hợp 2: Vẫn đoạn code đó nhưng thêm hàm fflush(stdout); ngay sau hàm print.

Trường hợp 3: Bỏ hàm fflush(stdout) và thay hàm printf thành printf("%d\n", i);

Chạy 3 đoạn chương trình đó và bạn sẽ thấy sự khác biệt rất thú vị. Hàm sleep(1) dùng để dừng chương trình 1s(không làm gì trong 1s này cả). Ở trường hợp thứ nhất, tất cả kí tự được in ra cùng 1 lúc sau 10s chạy chương trình, lí do là hàm printf chỉ đơn giản đưa các kí tự cần in ra màn hình vào stdout và chỉ in ra màn hình khi stdout được làm đầy hoặc không còn kí tự nào được đưa vào stdout nữa khi chương trình kết thúc, hoặc gặp kí tự xuống dòng(trường hợp 3). Ở trường hợp 2, hàm fflush(stdout) đưa tất cả kí tự được chứa trong stdout ra màn hình(làm sạch stdout).