2010-09-19 45 views
19

Nếu tôi cố gắng một cái gì đó như:Quét C đơn giản không hoạt động?

int anint; 
char achar; 

printf("\nEnter any integer:"); 
scanf("%d", &anint); 
printf("\nEnter any character:"); 
scanf("%c", &achar); 
printf("\nHello\n"); 
printf("\nThe integer entered is %d\n", anint); 
printf("\nThe char entered is %c\n", achar); 

Nó cho phép vào một số nguyên, sau đó bỏ qua thứ hai scanf hoàn toàn, điều này thực sự kỳ lạ, như khi tôi trao đổi hai (các char scanf đầu tiên), nó hoạt động tốt . Điều gì trên trái đất có thể sai?

+1

con trỏ của bạn có kích thước sai, anint là một char và achar là một int. đừng làm thế. –

+0

@Variable Length Coder: Tôi xin lỗi về điều đó, đã diễn giải một ví dụ đơn giản hơn và trộn lẫn với cả hai. Việc nhập nhầm đó không liên quan đến vấn đề của tôi, đã sửa ví dụ. – John

Trả lời

22

Khi đọc đầu vào sử dụng scanf, đầu vào được đọc sau khi phím Enter được nhấn nhưng xuống dòng được tạo ra bởi phím Enter không được tiêu thụ bởi scanf, có nghĩa là lần sau khi bạn đọc một char từ đầu vào tiêu chuẩn sẽ có một dòng mới đã sẵn sàng để đọc.

Một cách để tránh là sử dụng fgets để đọc các đầu vào như là một chuỗi và sau đó trích xuất những gì bạn muốn sử dụng sscanf như:

char line[MAX]; 

printf("\nEnter any integer:"); 
if(fgets(line,MAX,stdin) && sscanf(line,"%d", &anint)!=1) 
    anint=0; 

printf("\nEnter any character:"); 
if(fgets(line,MAX,stdin) && sscanf(line,"%c", &achar)!=1) 
    achar=0; 

Một cách khác để tiêu thụ xuống dòng sẽ được scanf("%c%*c",&anint);. %*c sẽ đọc dòng mới từ bộ đệm và loại bỏ nó.

Bạn có thể muốn đọc:

C FAQ : Why does everyone say not to use scanf?

+1

Bạn sẽ cần '% * c' sau định dạng'% d' (quá, hoặc thay thế), phải không? Mặc dù điều đó thậm chí không đáng tin cậy - nếu người dùng đã nhập một dấu cách hoặc thứ gì đó sau số và trước dòng mới. Tôi nghĩ 'fgets()' + 'sscanf()' là tốt hơn. –

+3

@ Jonathan: Bạn nói đúng. Chúng ta sẽ cần nó sau '% d'. Và có 'fgets + sscanf' luôn tốt hơn. – codaddict

+0

@codeaddict: Xin lỗi vì đã chấp nhận lâu, nhưng bạn thực sự đã cho tôi một số thông tin chi tiết hơn về cách thức hoạt động của nội bộ trong C. Tôi thực sự đánh giá cao liên kết C FAQ, tất cả những điều tốt hơn là khôn ngoan để dạy những người mới những điều này, nếu tôi đã từng giúp mọi người sau này. – John

5

Nó không bỏ qua giây thứ hai scanf(); số thứ hai scanf() đọc dòng mới bị bỏ lại bởi số scanf() đầu tiên. Hầu hết các mã định dạng bỏ qua khoảng trắng; định dạng %c không bỏ qua khoảng trắng.

12

Những câu trả lời khác là chính xác - %c không bỏ qua khoảng trắng. Cách đơn giản nhất để làm cho nó làm như vậy là đặt khoảng trắng trước %c:

scanf(" %c", &achar); 

(Bất kỳ khoảng trắng trong chuỗi định dạng sẽ làm cho scanf tiêu thụ tất cả các khoảng trắng liên tiếp).

+0

Làm cách nào để bỏ qua khoảng trắng giúp xóa bỏ dòng mới? Ví dụ: 'scanf (" \ n% c ", & achar);' cũng sẽ hoạt động. – cpx

+2

@cpx: Vì một dòng mới là khoảng trắng. Bất kỳ khoảng trắng nào trong chuỗi định dạng hoạt động giống như bất kỳ khoảng trắng nào khác, vì vậy '\ n' chỉ tốt bằng một khoảng trắng (nhưng một chữ cái khác). – caf

0

Hãy thử thêm _flushall() sau mỗi cuộc gọi printf. . Về cơ bản, theo mặc định, bộ đệm C++ của bộ đệm của MS sẽ làm cho luồng đầu ra bị trống.

0

gọi getchar() trước scanf cũng sẽ thanh lọc ngắt dòng được lưu trữ. Hơn trọng lượng nhẹ nhưng tình huống hơn

char input_1; 
char input_2; 
getchar(); 
scanf("%c", &input_1); 
getchar(); 
scanf("%c", &input_2); 

sẽ tuôn ra các ngắt dòng, hữu ích hơn trong dây chuyền liên tiếp của mã nơi bạn biết nó chỉ có một xếp hàng đợi giá trị và không phải là một chuỗi

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