Scanf và bộ đệm trong c

#include<stdio.h>

int main()
{
	char c;
	printf("......Enter q to quit......\n");
	do
	{
		printf("Enter a character\n");
		scanf("%c\n", &c);
		printf("%c\n", c);
	}
	while (c != 'q');
	return 0;
}

Anh chị cho em hỏi vì sao đoạn code scanf("%c\n", &c)'\n' mục đích của nó là gì thế ạ.
Em có tìm hiểu thì scanf("%c", &c) thì nó lấy kí tự người dùng nhập vào lưu vào biến c và cách xuống dòng (em không chắc có phải là '\n' không) lưu vào bộ đệm. Vậy thì scanf("%c\n", &c) nó khác gì với cái trên vậy ạ.
Em mới học C nên có gì sai sót mong anh chị thông cảm ạ.
Cảm ơn ac nhiều!

Bạn thử biền dịch rồi chạy thử là biết ngay;

3 Likes

Em chạy thử nhiều lần rồi mới lên đây hỏi chứ a.
Nhưng em vẫn không hiểu tại sao có '\n' vào thì nó lại như vậy.

Dòng lệnh scanf("%c\n", &c); có 2 bước:

  • %c đọc một ký tự bất kỳ.

  • \n đọc một ký tự bất kỳ mà không phải là whitespace (ký tự whitespace theo tui biết là những ký tự vô hình: ví dụ space, tab, enter, etc.);

  • Ví dụ 1: bạn nhập a xong ấn enter, trong bộ đệm sẽ có hai ký tự là ‘a’ và ‘\n’, ký tự ‘a’ thỏa xong bước một, ký tự ‘\n’ không thỏa bước 2 nên nó sẽ tiếp tục nhận input cho đến khi gặp ký tự non-whitespace.

  • Ví dụ 2: bạn nhập ab xong nhấn enter, trong bộ đệm sẽ có hai ký tự là ‘a’ và ‘b’ và ‘\n’, ký tự ‘a’ thỏa xong bước một, ký tự ‘b’ thỏa bước 2, gặp ký tự ‘\n’ input kết thúc.

Vấn đề về bộ đệm, ở ví dụ 2, ký tự ‘a’ được gán vào biến c và biến khỏi bộ đêm, ký tự ‘b’ và ‘\n’ vẫn còn trong đó, cho nên đến vòng lặp tiếp theo nó sẽ được “sử dụng”. Để giải quyết cách dễ nhất là sau mỗi lần nhận input xóa bộ đệm đi fflush(stdin);

4 Likes

Không chỉ là ký tự \n nha bạn, bất kỳ ký tự whitespace nào thay vào cũng như thế.

2 Likes

Oke anh đúng cái em cần rồi ạ. Cảm ơn a!.
Mà theo em được biết fflush(stdin); nó chỉ hỗ trợ ở một số trình biên dịch thôi ạ, vì fflush vs đầu vào stdin theo tiêu chuẩn C thì nó là hành vi không xác định. Lúc trước em thử dung nó trên ubuntu nhưng không hoạt động. Thay vào đó em dùng cái này while (( getchar ()) != '\n' ); ạ.

1 Like

Sau một hồi mày mò thì em đã tìm thấy một đáp án vừa lòng Đáp án eng

2 Likes
83% thành viên diễn đàn không hỏi bài tập, còn bạn thì sao?