2014-10-15 14 views
5

Tôi hiện đang đọc cuốn sách này "Lập trình C11 cho người mới bắt đầu" và trong chương scanf() nó nói:Tại sao thêm một không gian hàng đầu trong chuỗi định dạng scanf được khuyến nghị?

"Luôn thêm dấu cách trước ký tự chuỗi điều khiển đầu tiên để đảm bảo nhập ký tự chính xác." Như trong:

scanf(" %s", whatever); 

Chuỗi điều khiển% s, có khoảng trống trước nó. Tôi biết nó có vẻ khá tự giải thích, nhưng tôi không thực sự có được những gì có thể đi sai, và làm thế nào không gian này đảm bảo đầu vào nhân vật chính xác.

Xin cảm ơn trước.

+3

Điều đó tốt hơn đi kèm với một cảnh báo lớn 'char'% c' fetching có thể là lý do chi phối đằng sau tuyên bố sledge-hammer đó, và thất bại trong việc cung cấp các chi tiết cụ thể như vậy khiến tôi đặt câu hỏi về tư tưởng dạy học voodoo của văn bản đó."Luôn luôn làm " mà không có một số giải thích * tại sao * bạn nên làm theo câu thần chú đó, và làm thế nào mọi thứ có thể sai nếu bạn * không *, thường khó hiểu hơn là hữu ích (trường hợp tại điểm, bạn đăng câu hỏi này .. .). Dù sao, bạn có thể tìm thấy [** câu trả lời này **] (http://stackoverflow.com/questions/14419954/reading-a-single-character-in-c/14419972#14419972) hữu ích. – WhozCraig

+0

Cuốn sách đó có được gọi là * Lập trình C11 cho người mới bắt đầu * không? Không phải 'scanf' được thay thế bởi' scanf_s' trong C11? –

Trả lời

3

@WhozCraig cũng đã nêu rõ những thiếu sót đối với lời khuyên này. Nó đến mà không có lý trí và chi tiết. Hơn nữa, nó không áp dụng cho "%s""%s" tiêu thụ không gian trắng hàng đầu có hoặc không có không gian hàng đầu.

Một lãnh đạo trắng-không gian, có thể là ' ', '\t', '\n', vv tất cả làm điều tương tự: trực tiếp scanf() để tiêu thụ và không lưu trữ tùy chọn hàng đầu trắng-không gian char. Đây là hữu ích như sử dụng điển hình của trước scanf() không tiêu thụ của '\n' người dùng từ Nhập

scanf("%d", &some_int); 
scanf("%c", &some_char); // some_char is bound to get the value '\n' 

Tất cả scanf() specifiers đầu vào bỏ qua không gian hàng đầu, ngoại trừ 3: "%c", "%n", "%[]".

Đơn giản chỉ cần làm được hưởng lợi ích với không gian hàng đầu như sau. Không gian trắng còn lại trước đó được tiêu thụ trước '$'.

int Money; 
scanf(" $%d", &Money); 

Thông thường, mặc dù không phải luôn luôn là một không gian hàng đầu trước khi "%c" là có lợi như khi đọc một đơn char của người dùng nhập vào.

char ch; 
scanf(" %c", &ch); 

Điều gì là sai nhất với những lời khuyên là 1) khi sử dụng "%s", cung cấp một tham số chiều rộng là cần thiết để mã mạnh mẽ và 2) giá trị trả về phải được kiểm tra.

char buf[30]; 
int cnt = scanf("%29s", buf); 
if (cnt != 1) Handle_NoInput_or_EOF_IOError(); 

Cuối cùng, khuyên bạn nên sử dụng fgets() qua scanf() như người ta có thể - đó là trường hợp thông thường.

+0

Cảm ơn bạn chux :) Theo như tôi đã hiểu, khi sử dụng scanf() với "% c", "% n" hoặc "% []", scanf sẽ lưu trữ một không gian hàng đầu trong một char. Làm thế nào để nó lưu trữ trong cùng một char nếu char có thể chứa một ký tự duy nhất? – Stanley

+2

@Stanley 'scanf ("% c ", &ch);' sẽ tiêu thụ và loại bỏ không gian trắng tùy chọn. Sau đó, sẽ lưu trữ một 'không gian trắng' không gian '' trong 'ch'.' Scanf ("% c", &ch); ' sẽ lưu trữ 'char' đầu tiên đi kèm vào' ch'. '"% n "', hoặc '"% [] "' hoạt động khá khác nhau – chux

+0

Trên thực tế, nó áp dụng cho '% s' khi quét được áp dụng Tôi thường xuyên sử dụng 'scanf_s ("% [^ \ n] s ", mục tiêu);' để đọc một hàng đầy đủ mà không cần phải gặp rắc rối với các ký tự dòng mới - dẫn đầu hoặc theo sau. –

1

"Luôn thêm dấu cách trước ký tự chuỗi điều khiển đầu tiên để đảm bảo nhập ký tự chính xác".

Điều này là để tiêu thụ bất kỳ ký tự dấu sau trong stdin mà có thể đã được để lại bởi đầu vào người dùng trước đó (như carriage return), trước khi số scanf đọc đầu vào của người dùng.

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