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 ++;
}
这听起来像是家庭作业,所以这里有一些想法可以指导你(而不是直接给你答案):
- 您如何知道何时显示了数据屏幕
- (提示:您如何知道何时显示了一行数据?)
- 用户将如何表示他们已准备好进入下一页
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'当然可以检查您正在读取的文件中的行。您可以尝试了解其他人做了什么: