2010-01-23 40 views
14

stdout là dòng đệm khi kết nối với một thiết bị đầu cuối, nhưng tôi nhớ đọc ở đâu đó mà đọc (ít nhất là từ stdin) sẽ tự động tuôn ra stdout. Tất cả các triển khai C mà tôi đã sử dụng đã làm điều này, nhưng bây giờ tôi không thể tìm thấy nó trong tiêu chuẩn.Có đọc từ stdin flush stdout không?

Nó có ý nghĩa rằng nó hoạt động như vậy, nếu không mã như thế này:

printf("Type some input: "); 
fgets(line, sizeof line, stdin); 

sẽ cần thêm fflush(stdout);

Vậy là stdout đảm bảo được rửa ở đây?

EDIT:

Như nhiều trả lời đã nói, có vẻ là không đảm bảo trong tiêu chuẩn mà đầu ra để thiết bị xuất chuẩn trong ví dụ của tôi sẽ xuất hiện trước khi đọc từ stdin, nhưng mặt khác , ý định này được nêu trong (dự thảo rảnh rỗi bản sao) tiêu chuẩn:

các đầu vào và đầu ra năng động của thiết bị tương tác sẽ diễn ra theo quy định tại 7.19.3. Mục đích của các yêu cầu này là không có sản phẩm hoặc dòng đệm được xuất hiện ngay sau càng tốt, để đảm bảo rằng các thông báo thực sự xuất hiện trước một chương trình đang chờ đầu vào.

(ISO/IEC 9899: Bản thảo ủy ban TC2 - ngày 6 tháng 5 năm 2005, trang 14).

Vì vậy, có vẻ như không có bảo đảm, nhưng có thể nó sẽ hoạt động trong hầu hết các triển khai. (Những từ cuối cùng nổi tiếng ...)

+1

Theo tham chiếu chéo tới 7.19.3 (7.21.3 trong C11) cũng hữu ích, vì nó đề cập đến những hoạt động đầu vào nào được mong đợi sẽ gây ra xả. Chúng được thảo luận tại https://stackoverflow.com/a/39536803/8586227. –

Trả lời

4

Không, nó không.

+0

Nhưng nói chung những gì chúng ta thấy là stdout được flushed trước khi fgets line. Vì vậy, tại sao nó bị đỏ mặt ở đây. –

+0

Dường như thực hiện C được _allowed_ theo tiêu chuẩn để không in dấu nhắc trước các fgets, nhưng "intension" là nó nên, và tôi nghĩ rằng hầu hết (tất cả?) Triển khai thực hiện. –

+0

Theo ý định này sẽ làm cho tất cả đầu vào chậm hơn nhiều, và vì lợi ích đáng ngờ. –

4

No. Bạn cần fflush (stdout); Nhiều triển khai sẽ tuôn ra ở mỗi dòng mới của họ đang gửi đầu ra đến một thiết bị đầu cuối.

+0

AFIAK 'stdout' được yêu cầu theo tiêu chuẩn để được xếp hàng đệm hoặc không được xếp theo mặc định. – ybungalobill

5

Để trả lời câu hỏi của bạn, bạn làm cần thêm fflush(stdout); sau khi gọi printf() để đảm bảo lời nhắc xuất hiện trước khi chương trình của bạn cố đọc đầu vào. Đọc từ stdin không fflush(stdout); cho bạn.

4

Số stdin/stdout được đệm. Bạn cần phải giải thích fflush(stdout) để dữ liệu đệm trong bộ nhớ video/bộ nhớ của thiết bị đầu cuối unix được đẩy ra trên thiết bị xem như thiết bị đầu cuối. Có thể đặt bộ đệm của dữ liệu bằng cách gọi setvbuf.

Chỉnh sửa: Cảm ơn Jonathan, để trả lời câu hỏi, đọc từ stdin không tuôn ra stdout. Tôi có thể đã đi ra một ốp ở đây bằng cách xác định mã chứng minh làm thế nào để sử dụng setvbuf.

 
    #include 

    int main(void) 
    { 
    FILE *input, *output; 
    char bufr[512]; 

    input = fopen("file.in", "r+b"); 
    output = fopen("file.out", "w"); 

    /* set up input stream for minimal disk access, 
     using our own character buffer */ 
    if (setvbuf(input, bufr, _IOFBF, 512) != 0) 
     printf("failed to set up buffer for input file\n"); 
    else 
     printf("buffer set up for input file\n"); 

    /* set up output stream for line buffering using space that 
     will be obtained through an indirect call to malloc */ 
    if (setvbuf(output, NULL, _IOLBF, 132) != 0) 
     printf("failed to set up buffer for output file\n"); 
    else 
     printf("buffer set up for output file\n"); 

    /* perform file I/O here */ 

    /* close files */ 
    fclose(input); 
    fclose(output); 
    return 0; 
    } 

Hy vọng điều này sẽ giúp, Trân trọng, Tom.

+0

Mã của bạn liên quan đến hành vi của stdin và stdout như thế nào? –

+0

@ Jonathan: Đây là một mẫu làm thế nào để thiết lập bộ đệm cho đầu vào bằng cách sử dụng setvbuf là 512, hoặc bất kỳ hình nào cho vấn đề đó, tốt nhất là trên một ranh giới từ. Đó là một mẫu lấy từ tập tin trợ giúp trên trình biên dịch Borland C cho thấy việc sử dụng setvbuf. – t0mm13b

+0

Mã này là tốt như một câu trả lời cho một câu hỏi khác - nó không giải quyết các câu hỏi, đó là "không đọc từ stdin tuôn ra stdin". Tôi sẽ không phạt bạn cho một câu trả lời tiếp tuyến - nhưng tôi xem xét câu trả lời của bạn tiếp tuyến. –

2

Không, đó không phải là một phần của tiêu chuẩn.Chắc chắn bạn có thể đã sử dụng triển khai thư viện nơi hành vi mà bạn mô tả đã xảy ra, nhưng đó là tiện ích mở rộng không chuẩn mà bạn không nên dựa vào.

1

Không. Hãy cẩn thận để biết các khóa chết liên tiếp khi xử lý các luồng std khi đọc trên stdin hoặc viết trên khối stdout.

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