2011-11-09 34 views
6
#include<stdio.h> 
#include <unistd.h> 
int main(){ 
     while(1) 
     { 

       fprintf(stdout,"hello-out"); 
       fprintf(stderr,"hello-err"); 
       sleep(1); 
     } 
     return 0; 
} 

Khi biên soạn chương trình này trong gcc và khi thực thi nó chỉ in hello-err và không chào. Tại sao vậy? Ai đó có thể giải thích lý do đằng sau nó?tại sao chương trình c này không in câu lệnh printf đầu tiên?

+0

Nền tảng của bạn là gì? –

+0

Bạn đã xem văn bản in ở đâu? Đầu tiên 'printf' đang in thành' stdout' và thứ hai là 'stderr'.Trong trường hợp của bạn có thể là các luồng đầu ra khác nhau – Nekto

+0

@ JimBuck-Tôi đang làm việc trên Linux Fedora. – bornfree

Trả lời

17

Nếu bạn thêm '\n' vào thư của mình, nó sẽ (hoặc nên), ví dụ: "hello-out\n".

Lý do hạnh phúc là stdoutđệm để có hiệu quả hơn, trong khi stderr không đệm đó là đầu ra và là thích hợp hơn cho các thông báo lỗi và điều đó cần phải được in ngay lập tức.

stdout sẽ thường được đỏ mặt khi:

  • Một newline (\n) được in
  • Bạn đọc từ stdin
  • fflush() được gọi vào nó

EDIT: Điều khác tôi muốn thêm trước khi máy tính của tôi bị lỗi ... hai lần ... là bạn cũng có thể sử dụng setbuf(stdout, NULL); để vô hiệu hóa bộ đệm của stdout. Tôi đã làm điều đó trước khi tôi đã phải sử dụng write() (Unix) và không muốn đầu ra của tôi được đệm.

+0

+1 cho setbuf (stdout, NULL) –

+1

Cảm ơn bạn đã giải thích! – bornfree

+0

@bornfree: đừng lo lắng, hy vọng tôi giải thích nó ok. – AusCBloke

1

Bạn đã quên dòng mới (ghi chú \n) trong chuỗi của mình. Hoặc bạn cần phải gọi fflush(NULL); hoặc ít nhất fflush(stdout); trước sleep(1);

fprintf(stdout, ...) cũng giống như printf(...)

Bạn cần newlines đầu ra hoặc gọi fflush vì (ít nhất là trên Linux) bộ đệm stdout FILE là line- đệm. Điều này có nghĩa là thư viện C đang lưu trữ dữ liệu, và sẽ thực sự xuất nó (sử dụng write Linux system call) khi bộ đệm đủ đầy đủ hoặc khi bạn xóa nó bằng một dòng mới hoặc bằng cách gọi fflush. Việc đệm là cần thiết bởi vì các cuộc gọi hệ thống rất tốn kém (gọi write cho mỗi byte được xuất ra thực sự là quá chậm). Đọc thêm trang người đàn ông của setbuf

+1

Bạn có thể vui lòng giải thích tại sao yêu cầu đó không? Tôi muốn hiểu lý do đằng sau nó. – bornfree

+0

Câu trả lời của AusCBloke giải thích nó. –

+0

như những người khác đã trả lời, bởi vì nó được đệm để giảm hoạt động I/O. gọi fflush() sẽ buộc bộ đệm bị xóa. – LeleDumbo

3

Nó không luôn luôn in ra đầu ra để stdout bởi vì thiết kế stdout là BUFFERED đầu ra, và stderr là unbuffered. Nói chung, đối với luồng đầu ra được lưu vào bộ đệm, luồng không được đổ cho đến khi hệ thống "tự do" để làm như vậy. Vì vậy, dữ liệu có thể tiếp tục lưu vào bộ đệm trong một thời gian dài, trước khi nó bị xóa. Nếu bạn muốn để buộc các bộ đệm để tuôn ra bạn có thể làm như vậy bằng tay sử dụng fflush

#include<stdio.h> 
#include <unistd.h> 
int main(){ 
     while(1) 
     { 

       fprintf(stdout,"hello-out"); 
       fflush(stdout); /* force flush */ 
       fprintf(stderr,"hello-err"); 
       sleep(1); 
     } 
     return 0; 
} 

Cập nhật: stdout được linebuffered khi kết nối với một thiết bị đầu cuối, và chỉ đơn giản là đệm bằng cách khác (ví dụ như một chuyển hướng hoặc một ống)

+0

Cảm ơn! Tôi đã có điểm. – bornfree

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