C 逐页显示文件

C 逐页显示文件,c,file,file-handling,C,File,File Handling,我想做的是读取一个数据远远超过屏幕大小的文件,并根据用户响应逐页显示它 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(f

我想做的是读取一个数据远远超过屏幕大小的文件,并根据用户响应逐页显示它

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);    

有什么建议吗?

使用返回int的fgetc时,应设置读取字符数的自我限制

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();
    }
 }

我建议您选择一次在屏幕上打印的行数。在这里,我一次在屏幕上选取50行,然后显示器等待用户的输入

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

这听起来像是家庭作业,所以这里有一些想法可以指导你(而不是直接给你答案):

  • 您如何知道何时显示了数据屏幕
  • (提示:您如何知道何时显示了一行数据?)
  • 用户将如何表示他们已准备好进入下一页
如果你提出正确的问题,问题往往会自动得到解答。

让我详细介绍一下。不要再发明轮子了。您的用户将更乐于使用他们已经知道如何从其他程序配置和使用的解决方案(以及界面)。UNIX的做事方式是只做一件事,然后把它做好。能够很好地显示输出页面的程序称为寻呼机。过去有,但现在有了更好的选择

寻呼机将通过其标准输入流接收要显示的内容,然后以任何奇特的方式将其呈现给用户。您应该让用户选择寻呼机程序。执行此操作的一个好方法是检查环境变量
PAGER
,以获取要作为寻呼机执行的命令。如果您正在这样做,请注意环境不总是可信的。如果您的程序是
stuid()
ed,那么从环境变量执行代码将是一个非常糟糕的主意,因此在这种情况下,您最好忽略它。有些人喜欢提供更特殊的
MYPROGRAM\u PAGER
变量,只有在未设置该变量时,才检查更通用的
PAGER
变量

您应该检查的另一件事是是否为标准输出。如果不是,只需一次转储所有输出。由于它将被重定向到一个文件,因此它既不会溢出屏幕(因此寻呼机不会有任何好处),也不会让用户愿意或甚至能够按enter键(因此寻呼机实际上会有坏处)

生成的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;
}

我在这个问题上花费了相当多的细节,因为到目前为止最让我烦恼的是程序与用户的交互是否很差。不幸的是,许多编程教程一开始都是关于用户交互的糟糕例子,可能是因为作者自己从来没有真正使用过命令行工具。在许多(如果不是全部)命令行工具上,一个一致的良好用户体验是我认为可用计算机的最重要的方面。

你认为这行吗?if(ch='\n'){count++;if(count%100==0)ch='\n'当然可以检查您正在读取的文件中的行。您可以尝试了解其他人做了什么: