2009-08-26 20 views
37

Tôi muốn thực hiện một thanh tiến trình cho các ứng dụng thiết bị đầu cuối của tôi rằng sẽ làm việc gì đó như:Làm thế nào để cập nhật một thông điệp được in trong thiết bị đầu cuối mà không cần in lại (Linux)

[XXXXXXX  ] 

mà sẽ cung cấp một dấu hiệu cho thấy hình ảnh của bao nhiêu thời gian còn lại trước khi quá trình hoàn tất.

Tôi biết tôi có thể làm điều gì đó như in ngày càng nhiều của X bằng cách thêm chúng vào chuỗi và sau đó chỉ cần printf, nhưng điều đó sẽ trông giống như:

[XXXXXXX  ] 
[XXXXXXXX  ] 
[XXXXXXXXX  ] 
[XXXXXXXXXX ] 

hoặc một cái gì đó như thế (rõ ràng là bạn có thể chơi với khoảng cách.) Nhưng đây không phải là thẩm mỹ trực quan. Có cách nào để cập nhật văn bản đã in trong thiết bị đầu cuối có văn bản mới mà không cần in lại không? Đây là tất cả dưới Linux, C++.

Trả lời

40

thử sử dụng \r thay vì \n khi in "phiên bản" mới.

for(int i=0;i<=100;++i) printf("\r[%3d%%]",i); 
printf("\n"); 
+0

hoạt động như một nét duyên dáng, cảm ơn – ldog

8

Tôi muốn nói rằng thư viện như ncurses sẽ được sử dụng cho những thứ như vậy. lời nguyền giúp di chuyển con trỏ xung quanh màn hình và vẽ văn bản và như vậy.

NCurses

+6

Âm thanh như một mức quá mức cần thiết ở đây. –

+1

Vâng, có lẽ ... chỉ là một gợi ý nếu ai đó muốn trở nên ưa thích hơn trong tương lai;) – KFro

+3

Vâng ... có thể có một trò chơi PONG đang diễn ra trong khi chúng tôi đợi thanh tiến trình. : D – kjfletch

6

Something như thế này:

std::stringstream out; 
for (int i = 0; i< 10; i++) 
{ 
    out << "X"; 
    cout << "\r" << "[" << out.str() << "]"; 
} 

Bit lén lút là nhân vật vận chuyển trở lại "\ r" mà làm cho con trỏ để di chuyển đến đầu dòng mà không đi xuống tiếp theo hàng.

1

'\ r' sẽ thực hiện trả lại vận chuyển. Hãy tưởng tượng một máy in đang hoạt động trở lại mà không có một linefeed ('\ n'). Thao tác này sẽ trả về điểm viết trở lại đầu dòng ... sau đó in lại trạng thái đã cập nhật của bạn ở đầu dòng gốc.

1

Đó là ngôn ngữ khác, nhưng this question có thể hỗ trợ bạn. Về cơ bản, ký tự escape \ r (vận chuyển Return, ngược với \ n Newline) sẽ đưa bạn trở lại đầu dòng in hiện tại của bạn để bạn có thể ghi đè lên những gì bạn đã in.

1

Một tùy chọn khác là chỉ cần in một ký tự cùng một lúc. Thông thường, stdout được dòng đệm, vì vậy bạn sẽ cần phải gọi fflush (stdout) -

for(int i = 0; i < 50; ++i) { 
    putchar('X'); fflush(stdout); 
    /* do some stuff here */ 
} 
putchar('\n'); 

Nhưng điều này không có chấm dứt đẹp "]" mà chỉ hoàn thành.

3

Những người khác đã chỉ ra rằng bạn có thể sử dụng \r để quay lại phần đầu của dòng hiện tại và ghi đè toàn bộ dòng.

Một khả năng khác là sử dụng ký tự backspace ("\ b") để xóa một vài khoảng trắng và chỉ ghi đè các khoảng trắng đó. Điều này có thể có một vài lợi thế. Đầu tiên, nó rõ ràng là tránh phải tái tạo tất cả mọi thứ trong dòng, mà đôi khi có thể được đau đớn nhẹ (mặc dù đó là khá bất thường). Thứ hai, nó có thể tránh một số cơn đau trong việc hiển thị dữ liệu (ví dụ một) thu nhỏ kích thước khi bạn viết nó - ví dụ, nếu bạn đang hiển thị đếm ngược từ 100 đến 0, với \r bạn phải cẩn thận về ghi đè toàn bộ chiều dài trước đó, hoặc đếm ngược của bạn sẽ đi từ (ví dụ) 100 đến 990 (ví dụ, để nguyên "0" trước đó).Tuy nhiên, lưu ý rằng mặc dù back-space trong một dòng thường hoạt động, một backspace ở đầu của một dòng có thể hoặc không thể di chuyển vị trí con trỏ/ghi lại một dòng trước đó. Đối với hầu hết các mục đích thực tế, bạn chỉ có thể di chuyển xung quanh trong một dòng duy nhất.

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