2014-12-21 51 views
-1

我想要做的是讀取一個文件,其數據遠大於屏幕尺寸,並基於用戶響應逐頁逐頁顯示。逐頁顯示文件

fp = fopen(empRecord.dat,"rb"); // read mode 

if(fp == NULL) 
{ 
    perror("Error while opening the file.\n"); 
    exit(EXIT_FAILURE); 
} 

printf("The contents of %s file are :\n",empRecord.dat); 

while((ch = fgetc(fp)) != EOF) 
    printf("%c",ch); 

fclose(fp);  

有什麼建議嗎?

+0

你可以嘗試找出其他人做了什麼:http://www.greenwoodsoftware.com/less/download.html –

回答

0

while using fgetc which returns an int you should set a limit limit on the no of read read。

while((ch = fgetc(fp)) != EOF) 
    printf("%c",ch); 

無論限制如何,您只需一頁100個字符。

int i=0; 
while((ch = fgetc(fp)) != EOF) 
{ 
    i++; 
    printf("%c",ch); 
    if(i==100) 
    { 
    printf("you want to see more...(1/0)"); 
    scanf("%d",choice); 
    if(choice!=1) 
     break; 
    else 
    clrscr(); 
    } 
} 
+0

你認爲這將作爲行? if(ch =='\ n') count ++; if(count%100 == 0) –

+0

ch =='\ n'肯定會用於檢查您正在閱讀的文件中的行。 –

0

我會建議挑一次行在屏幕上打印一次。在這裏,我一次在屏幕上選取50行,然後顯示屏等待用戶的輸入。

int cnt =0; 
while((fgets(buf,sizeof(buf),fp)) != NULL) 
{ 
    printf("%s",buf); 
    if(cnt == 50) 
    { 
    getchar(); 
    cnt =0; 
    } 
    cnt ++; 
} 
1

這聽起來像功課,所以這裏有一些想法來指導你(不直接給你的解決方案):

  • 你怎麼會知道當你的數據顯示的畫面?
  • (提示:您將如何知道您何時顯示了一行數據?)
  • 用戶將如何表明他們已準備好進入下一頁?

如果您提出正確的問題,常常會有問題自行回答。

0

讓我在Peter Schneider's comment上展開一點。不要重新發明輪子。您的用戶會對解決方案(以及接口)感到高興,他們已經知道如何配置和使用其他程序。 UNIX的做事方式是做一件事,做得很好。確實顯示輸出頁面的程序稱爲頁面。曾經有more,但現在less是一個更好的選擇。

尋呼機將通過其標準輸入流接收顯示內容,然後以任何奇特的方式呈現給用戶。您應該將尋呼機程序的選擇留給用戶。這樣做的一個好方法是檢查環境變量PAGER以獲得作爲尋呼機執行的命令。如果您正在這樣做,請注意環境不總是可信的。如果你的程序是stuid() ed,那麼從一個環境變量中執行代碼是一個非常糟糕的主意,所以你最好在這種情況下忽略它。有些人喜歡提供更加特殊的MYPROGRAM_PAGER變量,只有在沒有設置的情況下才會檢查更一般的PAGER變量。

你應該檢查的另一件事是標準輸出isatty()。如果不是,只需將所有輸出一次性轉儲出去。由於它將被重定向到一個文件,它也不會溢出屏幕(所以尋呼機不會有任何好處),用戶也不會願意甚至不能進入(所以尋呼機實際上會變差)。

生成的C程序應該看起來相當簡單。

#define _GNU_SOURCE 

#include <errno.h> 
#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 
#include <unistd.h> 

int 
produce_output(FILE *const stream, const unsigned lines); 

int 
main(const int argc, const char *const *const argv) 
{ 
    unsigned lines; 
    if (argc != 2) 
    { 
     fprintf(stderr, "error: wrong number of arguments\n"); 
     return EXIT_FAILURE; 
    } 
    else 
    { 
     char * endptr; 
     long val = strtol(argv[1], &endptr, 0); 
     if (*endptr != '\0' || val < 0) 
     { 
      fprintf(stderr, "error: not a non-negative integer: %s\n", argv[1]); 
      return EXIT_FAILURE; 
     } 
     lines = val; 
    } 
    if (isatty(fileno(stdin)) && isatty(fileno(stdout))) 
    { 
     const char * pager_command = NULL; 
     FILE * pager_pipe = NULL; 
     const char *const env_vars[] = {"MYPROG_PAGER", "PAGER", NULL}; 
     unsigned i; 
     for (i = 0; env_vars[i] != NULL; ++i) 
     { 
      if ((pager_command = secure_getenv(env_vars[i])) != NULL) 
      break; 
     } 
     if (pager_command == NULL) 
     pager_command = "less -XRF"; /* sane default */ 
     pager_pipe = popen(pager_command, "w"); 
     if (pager_pipe == NULL) 
     { 
      fprintf(stderr, 
        "error: popen(\"%s\", \"w\"): %s\n", 
        pager_command, strerror(errno)); 
      return EXIT_FAILURE; 
     } 
     /* Write everything to the pager at once. */ 
     if (produce_output(pager_pipe, lines) < 0) 
     fprintf(stderr, "warning: I/O error: %s\n", strerror(errno)); 
     if (pclose(pager_pipe) < 0) 
     { 
      fprintf(stderr, "error: pclose(): %s\n", strerror(errno)); 
      return EXIT_FAILURE; 
     } 
    } 
    else 
    { 
     /* Write everything to stdout at once. */ 
     if (produce_output(stdout, lines) < 0) 
     fprintf(stderr, "warning: I/O error: %s\n", strerror(errno)); 
    } 
    return EXIT_SUCCESS; 
} 

int 
produce_output(FILE *const stream, const unsigned lines) 
{ 
    unsigned i; 
    for (i = 1; i <= lines; ++i) 
    { 
     const char * suffix; 
     switch(i) 
     { 
     case 1: suffix = "st"; break; 
     case 2: suffix = "nd"; break; 
     case 3: suffix = "rd"; break; 
     default: suffix = "th"; break; 
     } 
     if (fprintf(stream, "This is the %d%s line of output.\n", i, suffix) < 0) 
     return -1; 
    } 
    if (fflush(stream) < 0) 
    return -1; 
    return lines; 
} 

secure_getenv是GNU擴展爲getenv封裝檢查環境是否可以信任你。

如果你想讓你的程序更健壯,你可以實現你自己的普通尋呼機,並在外部工具不可用時使用它作爲後備。在上面的例子中,我簡單地回到了一個硬編碼的默認值。

要測試您的程序,請考慮以下情況。

./myprog 10          # short amount of output 
./myprog 1000         # large amount of output 
PAGER='less -M' ./myprog 100      # use 'less -M' as pager 
MYPROG_PAGER='cat' ./myprog 100     # use 'cat' as a "pager" 
MYPROG_PAGER='cat' PAGER='less -M' ./myprog 100 # use 'cat' as a "pager" 
./myprog 100 | cat        # output is not at TTY 
./myprog 100 > /dev/full       # output is a bad file 
sudo chown root:root myprog 
sudo chmod u+s myprog 
./myprog 100          # use default pager 
PAGER='silly' ./myprog 100      # must ignore 'silly' in setuid'ed program 

我在這個問題上花費相當長的一段細節,因爲什麼迄今爲止最讓我生氣是如果的程序與用戶交互不佳。不幸的是,許多編程教程都以用戶交互的可怕示例開始,可能是因爲作者從來沒有真正使用命令行工具。跨許多(如果不是全部)命令行工具的一致的良好用戶體驗是我認爲可用計算機最重要的方面。