2011-01-23 28 views
8

Tôi đang học lập trình trong C và muốn có thể nhập các ký tự vào thiết bị đầu cuối trong khi mã của tôi đang chạy mà không cần nhấn trả lại. Chương trình của tôi hoạt động, tuy nhiên khi tôi gọi initscr(), màn hình sẽ bị xóa - ngay cả sau khi gọi filter(). Tài liệu cho số filter đề nghị bạn nên tắt thanh toán bù trừ - tuy nhiên đây không phải là trường hợp của tôi.Làm thế nào để sử dụng getch từ những lời nguyền mà không cần xóa màn hình?

#include <stdio.h> 
#include <curses.h> 
#include <term.h> 

int main(void) { 

    int ch; 

    filter(); 
    initscr(); 
    cbreak(); 
    noecho(); 
    keypad(stdscr, TRUE); 

    while((ch = getch()) != EOF); 

    endwin(); 

    return 0; 
} 

Tại sao mã trên vẫn xóa màn hình và có thể làm gì để khắc phục?

Tôi đang sử dụng Debian Lenny (ổn định) và gnome-terminal nếu có ích.

+0

Đối PDCurses bạn có thể thiết lập các biến môi trường PDC_PRESERVE_SCREEN hoặc PDC_RESTORE_SCREEN với bất kỳ giá trị: từ file LỊCH SỬ: – Brandin

+0

PDC_PRESERVE_SCREEN Nếu biến môi trường này được đặt, PDCurses sẽ không xóa màn hình thành màu trắng mặc định trên nền đen khi khởi động. Điều này cho phép bạn che phủ một cửa sổ phía trên cùng của nền màn hình hiện tại. PDC_RESTORE_SCREEN Nếu biến môi trường này được đặt, PDCurses sẽ chụp một bản sao của nội dung của màn hình tại thời điểm PDCurses được bắt đầu; initscr(), và khi endwin() được gọi, màn hình sẽ được khôi phục. – Brandin

Trả lời

2

Sử dụng newterm() thay vì initscr(), bạn sẽ ổn thôi. Và đừng quên về delscreen() nếu bạn làm theo lời khuyên này.

+0

Xin chào, cảm ơn bạn đã trả lời, tôi đã thử những gì bạn nói và chức năng giống nhau - màn hình đã bị xóa một lần nữa. Thay cho 'initscr()' tôi có 'FILE * fild_id = fopen ("/dev/tty "," r + "); SCREEN * termref = newterm (NULL, file_id, file_id); 'và thay vì' endwin() 'Tôi có' delscreen (termref) '. –

+0

Lạ nhưng nó không xóa màn hình của tôi khi tôi sử dụng nó thay vì 'initscr()'. Tôi gọi nó là 'newterm (NULL, stdin, stdout)' mặc dù. –

+3

Lý do duy nhất nó không xóa màn hình của bạn, Mike, là bạn đảo ngược các đối số để newterm(). Nó mất stdout, stdin, không stdin, stdout. Tôi đặt cược sau khi chương trình thử nghiệm của bạn chạy, đầu vào của bạn là sai lầm? Không có tiếng vang, có lẽ? Nếu bạn sử dụng thứ tự đối số chính xác cho newterm() nó thực sự xóa màn hình. Câu trả lời của bạn là sai. –

4

Mở rộng câu trả lời bằng mike.dld, tính năng này hoạt động với tôi trên MacOS X 10.6.6 (GCC 4.5.2) với thư viện hệ thống nguyền rủa - mà không xóa màn hình. Tôi đã thêm khả năng ghi lại các ký tự được nhập (đăng nhập vào một tệp "x") và khả năng nhập CONTROL-D và dừng chương trình thay vì buộc người dùng phải ngắt.

#include <stdio.h> 
#include <curses.h> 
#include <term.h> 

#define CONTROL(x) ((x) & 0x1F) 

int main(void) 
{ 
    FILE *fp = fopen("x", "w"); 
    if (fp == 0) 
     return(-1); 
    SCREEN *s = newterm(NULL, stdin, stdout); 
    if (s == 0) 
     return(-1); 
    cbreak(); 
    noecho(); 
    keypad(stdscr, TRUE); 

    int ch; 
    while ((ch = getch()) != EOF && ch != CONTROL('d')) 
     fprintf(fp, "%d\n", ch); 

    endwin(); 

    return 0; 
} 
+0

Cảm ơn guys đã trả lời, điều này làm việc hoàn hảo –

+0

Điều này làm rõ màn hình cho tôi (vì vậy nó không hoạt động). – nh2

+0

@ nh2: nó có thể phụ thuộc vào loại thiết bị đầu cuối của bạn và mục nhập cảnh báo bạn đang sử dụng. –

0

Về cơ bản, lời nguyền được thiết kế để chiếm đoạt màn hình (hoặc cửa sổ, trong trường hợp cửa sổ có cửa sổ). Bạn có thể không thực sự trộn lời nguyền với stdio, và bạn không thể thực sự sử dụng lời nguyền để chỉ cần đầu vào hoặc đầu ra một cái gì đó mà không gây rối với phần còn lại của màn hình. Có cách giải quyết một phần, nhưng bạn sẽ không bao giờ thực sự có thể làm cho nó hoạt động theo cách mà nó giống như bạn muốn. Lấy làm tiếc.

Tôi khuyên bạn nên viết lại chương trình của mình để sử dụng các lời nguyền trong suốt hoặc điều tra các lựa chọn thay thế như readline.

+0

readline sử dụng ncurses nội bộ. –

+1

readline chỉ sử dụng giao diện termcap –

1

Bạn sẽ thấy màn hình của bạn xóa trong một ứng dụng lời nguyền vì một trong những lý do sau:

  • chương trình của bạn gọi initscr (mà xóa màn hình) hoặc newterm mà không gọi filter, hoặc
  • việc khởi tạo thiết bị đầu cuối xóa màn hình (hoặc làm cho màn hình hiển thị rõ ràng, bằng cách chuyển sang màn hình thay thế).

Trong trường hợp sau, bạn có thể ngăn chặn các tính năng màn hình thay thế trong ncurses bằng cách đặt lại enter_ca_modeexit_ca_mode con trỏ đến NULL as done in dialog. Tốt hơn, hãy chọn một mô tả thiết bị đầu cuối thực hiện những gì bạn muốn.

Đọc thêm:

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