2017-06-09 29 views
0

display_text.c 该程序不使用字符串作为缓冲器的矩阵,而是直接读出的文本字符串。 文本必须显示为由40行分别组成的页面。 打印第一页后,程序将显示一个提示>>并等待用户的命令。从文本文件中读取行,打印其中的40行,并且“必须”使用系统调用lseek或fseek来更改偏移量?

命令是:

n: to show next page 
p: to show previous page 
q: to quit the program 

该程序使用系统调用lseek(fd, offset, mode)fseek()。 注意行数有不同长度的事实!

//LIBRARIES 
#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 

//GLOBAL VARS 
const char *filename = NULL;  //file name 
FILE *file;      //file stream 
int page_number=1;    //number of current page 
int line_count; 
int page_total=0; 

//PROTOTYPES METHODS 
int prompt(void); 
int print_page(int num_page_print); 

int main(int argc, char *argv[]) { 
    int i; //loop counter 
    char name[50]; //name of file 

    //read the name of the file from command line 
    if(argc!=2) { 
     printf("Specify input on command line.\n"); 
     scanf("%s", name); 
     filename = name; 
    } 
    else if(argv[1]!=NULL) 
      filename=argv[1]; 
     else 
      return 1; //error 

    //try to open the file 
    file=fopen(filename, "rt"); 
    if(file == NULL){ 
     printf("Cannot open the file! %s \n",filename); 
     return 1; //error 
    } 
    prompt();      //call for prompt 
    fclose(file);     //close file 
    return 0;      //everything has gone as supposed :-) 
} 

int prompt(void) { 
    char *cmd=NULL;     //cmd 
    cmd=malloc(2*sizeof(char*));   //allocate two bit for command 
    char line[100]; 

    while(fgets(line, sizeof(line), file)!=NULL) //count file lines 
     line_count++; 

    rewind(file); 

    //number of total pages 
    if(line_count%40==0) 
     page_total=line_count/40; 
    else 
     page_total=line_count/40+1; 

    //printf("\nTotal pages are %d\n",page_total); 
    //while cmd!=q, continue to show prompt >> 
    while(1){ 
     //VIEW ALL COMMANDS 
     printf("a: next page; i: previous page; q: quit\n"); 
     printf(">> "); 
     scanf("%s", cmd); 
     //next page 
     if(page_number!=page_total && strcmp(cmd,"n")==0){ 
      print_page(page_number+1);    //print next page 
      page_number++;       //update number of page 
     } 
     //prev page 
     if(page_number!=1 && strcmp(cmd,"p")==0){ 
      print_page(page_number-1);    //print prev page 
      page_number--;       //update number of page 
     } 
     //exit 
     if(strcmp(cmd, "q")==0){ 
      free(cmd);      //free memory 
      return 0;       //success, return zero 
     } 
    } 
} 
//My problems start here 
int print_page(int num_page_print) { 
    char line[100]; 
    int i; 

    if(num_page_print < page_number) 
     //fseek change offset to print prev page 
    else 
     //fseek change offset to print next page 

    for(i = 0; i < 40; i++) { 
     fread(line, sizeof(line),1, file); 
     //how do I print lines that have different lengths! 
     printf("[%d] %s\n",i+1, line); 
    } 
} 
//Any comments, reccomendations and critics are welcome :-)` 

我想:先打印给定file.txt的40线,但因为我是直接从文件中读取,输出我得到的是,超过40行印刷,大概是因为char line[100]串被预定义,如果你能告诉我如何打印那些尺寸不同的线条,那将是非常棒的!

+0

'的scanf( “%S”,姓名);'< - 缓冲区溢出。 –

+3

你有什么问题要问吗?另外,你应该检查'malloc'的返回值以及打印和错误,例如,如果失败,则使用'perror'。 – Badda

+0

我有麻烦试图打印完整的.txt文件的40行,并使用fseek()来管理打印方法,其余工作正常,因为已经在另一个程序中使用 – Midnight

回答

0

两个功能,允许线在文件中的行轻松阅读。

第一个是getline()我建议你使用。你可以阅读关于它here。这个函数的优点是它根据你正在阅读的行的长度自动地为你的存储变量分配正确的大小。不幸的是没有C的版本实现getline()。它不是C标准的一部分,而是POSIX.1-2008的一部分,所以你只能在符合这个标准的系统上使用它。

另一个功能,不太友善的使用是fgets()哪些文档是here

在这两种情况下,你只需要做出一个循环迭代其40倍,例如:

char* storingVariable = NULL; 
size_t len = 0; 
for (int i = 0; i != 39; getline(&storingVariable, &len, inFile)) 
    printf("Line is : %s\n", storingVariable); 

使用getline()的常用方法如下:

int i = 0; 
char* storingVariable = NULL; 
size_t len = 0; 
while (getline(&storingVariable, &len, inFile) != -1) // This allows to read until the end of the file 
{ 
    printf("Line is : %s\n", storingVariable); 
    i++; 
    if (i == 39) 
     break; 
} 
// free the storing variable if you don't need it 

我最近问了一个​​,这可能会比我刚刚做得更详细。

+0

谢谢!!!!!!!!!!!!! – Midnight

+0

@Midnight没问题。如果它解决了你的问题,请接受答案,如果你需要更多的解释/细节,请不要犹豫,评论一些问题。 – Badda

+1

由于'getline()'是POSIX,因此可能需要使用功能测试宏来使其在某些系统上可以使用;这个细节可能值得添加答案。此外,当达到文件结束时,getline()会返回“-1”,所以你的第二个例子不能按预期工作。 –

相关问题