2013-08-28 71 views
6

Hãy xem xét đoạn mã sau C:Sự khác nhau giữa scanf ("% c", & c) và scanf ("% c", & c)

#include <stdio.h> 

int main() 
{ 
    int a; 
    char c; 
    scanf("%d",&a); 
    scanf("%c",&c); 
    printf("int=%d\n",a); 
    printf("char=%c\n",c); 
} 

tôi có thể đầu vào chỉ số nguyên và không phải là đầu ra character.The chỉ đơn giản là giá trị số nguyên và không có giá trị là đầu ra cho câu lệnh printf thứ hai.

Tuy nhiên nếu tôi sử dụng một không gian trước khi sự xác định định dạng:

scanf(" %c",&c); 

Nó hoạt động như mong đợi. Tại sao điều này là trường hợp?

Có người nói với tôi rằng nó có liên quan đến việc xóa bộ đệm đầu vào. Ai đó có thể làm sáng tỏ một chút?

Trả lời

8

Sự khác biệt giữa scanf("%c", &c1)scanf(" %c", &c2) là các định dạng mà không có sự trống đọc ký tự tiếp theo, thậm chí nếu nó là không gian màu trắng, trong khi một với skips trống khoảng trắng (bao gồm cả dòng mới) và đọc ký tự tiếp theo đó không phải là khoảng trắng.

Ở định dạng scanf(), trống, tab hoặc dòng mới có nghĩa là 'bỏ qua khoảng trắng nếu có bất kỳ để bỏ qua'. Nó không trực tiếp 'xóa bộ đệm đầu vào', nhưng nó ăn bất kỳ khoảng trắng nào trông giống như xóa bộ đệm đầu vào (nhưng hoàn toàn khác với bộ đệm đầu vào). Nếu bạn đang sử dụng Windows, sử dụng fflush(stdin) sẽ xóa bộ đệm đầu vào (trong khoảng trắng và các ký tự khoảng trắng); trên Unix và theo tiêu chuẩn C, fflush(stdin) là hành vi không xác định.

Ngẫu nhiên, nếu bạn gõ số nguyên theo sau ngay lập tức bằng dấu xuống dòng, đầu ra của chương trình kết thúc bằng hai dòng mới: đầu tiên là c và số thứ hai trong chuỗi định dạng. Do đó, bạn có thể đã thấy:

$ ./your_program 
123 
int=123 
char= 

$ 

Tức là, scanf() đọc dòng mới làm đầu vào của nó. Xem xét một phương thức thay thế khác:

$ ./your_program 
123xyz 
int=123 
char=x 
$ 

Ngõ vào số nguyên dừng khi đọc 'x'; đầu vào ký tự do đó đọc 'x'.

+0

Bạn có thể cho biết sự khác biệt giữa việc xóa và bỏ qua bộ đệm không, tôi khá bối rối ở đây? –

+0

Sự khác biệt là chính tả - năm ký tự trước 'ing'. Không có ý nghĩa xác định cho 'xóa' hoặc 'bỏ qua'. Tôi đoán rằng nếu tôi chọn một ý nghĩa, 'xóa' sẽ liên quan đến lập trình viên trong một số công việc rõ ràng, trong khi 'bỏ qua' xảy ra bên trong hàm '-family' của' scanf mà không có bất kỳ công việc rõ ràng nào của lập trình viên, nhưng nó mở cho thảo luận và những người khác có thể có các định nghĩa thay thế hợp pháp sẽ làm việc chặt chẽ. –

2

Bởi vì sau khi bạn nhập số và nhấn ENTER, dòng mới nằm trong bộ đệm và sẽ được xử lý bởi số thứ hai scanf.

Tóm lại, bạn đã lưu dòng mới trong biến c.

Tuy nhiên, nếu bạn sử dụng

scanf(" %c",&c); 
// ^

không gian sẽ tiêu thụ dòng mới, mà làm cho c giá trị mà bạn mong đợi.

-1

Bạn phải vượt qua một con trỏ đến đối tượng dữ liệu theo quy định của chuỗi định dạng, vì vậy

scanf("%c", c); 

sẽ thực sự vượt qua giá trị của c, do đó có thể gây ra một lỗi chương trình,

scanf("%c", &c); 

sẽ chuyển địa chỉ của c, cho phép scanf thay đổi giá trị của bản sao của bạn.

Không gian sau% c sẽ bắt buộc tìm kiếm một ký tự VÀ THÌ một khoảng trắng. Nếu không có không gian, nó sẽ không đọc ký tự

+1

Điều này thậm chí không cố gắng trả lời câu hỏi tại sao không gian làm cho 'scanf' hoạt động chính xác. Thêm vào đó, không có nơi nào trong câu hỏi OP đề xuất sử dụng 'scanf ("% c ", c)'. – user4815162342

+0

Ngoài ra, một dấu cách trong một chuỗi định dạng là một thảm họa nhỏ, ít nhất là cho một chương trình tương tác; nó không hài lòng cho đến khi nó đọc, và sau đó đẩy lùi lại, một ký tự không gian trắng. Vì vậy, bạn có thể nhập 'x' và trả về, nhưng 'scanf ("% c ", & c)' sẽ không trả lại cho đến khi bạn nhập thứ gì đó khác với dấu cách hoặc tab. –

Các vấn đề liên quan