0

display_text.c The program doesn't use a matrix of strings as buffer but reads directly the strings from the text. Text must be shown as pages composed of 40 lines each. After printing the first page, the program shows a prompt >> and wait for the user's command.

Commands are:

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

The program uses the system call lseek(fd, offset, mode) or fseek(). Pay attention to the fact the rows have different length !

//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 :-)`

I would like to: first print 40 lines of a given file.txt, but since I am reading directly from file, the output I get is that more than 40 lines are printed, probably because the char line[100] string is predefined, if you could suggest me how to print those lines that have different size that would be great!

HDJEMAI
  • 9,436
  • 46
  • 67
  • 93
Midnight
  • 1
  • 1
  • `scanf("%s", name);` <- buffer overflow. –  Jun 09 '17 at 08:05
  • 3
    Do you have any question to ask ? Also, you should check the return of `malloc` and print and error, for example with `perror` if it failed. – Badda Jun 09 '17 at 08:05
  • I have troubles trying to print exactly 40 lines of a .txt file and using fseek() to manage the printing method, the rest works fine since already used in another program – Midnight Jun 09 '17 at 08:08
  • 1
    "I have problem" is quite a broad question. What exactly is not working ? Errors ? If so, show them. Unexpected output ? If so, show it along with the expected output. Please edit your question accordingly. – Badda Jun 09 '17 at 08:11
  • Ok, sorry i will get more specific!! I would like to: first print 40 lines of a given file .txt, but since I am reading directly from file, the output I get is that more than 40 lines are printed, probably because the char line[100] string is predefined, if you could suggest me how to print those lines that have different size that would be great! – Midnight Jun 09 '17 at 08:12

1 Answers1

0

Two functions allow to read easily in file line by line.

The first one is getline() which I advise you use. You can read about it here. The advantage of this function is that it allocates automatically the correct size to your storing variable depending of the length of the line you are reading. Unfortunately no version of C implements getline(). It's not part of the C standard but of POSIX.1-2008, so you can only use it on systems conforming to this standard.

Another function, a bit less friendly to use is fgets() which documentation is here.

In both case, you'll just have to make a loop which iterates 40 times, for example :

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

The usual way to use getline() is the following :

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

I asked a similar question recently which could may be help you in a much more detailled way than I just did.

Badda
  • 1,329
  • 2
  • 15
  • 40
  • @Midnight No problem. Please accept the answer if it solved your problem and don't hesitate to comment some questions if you need any more explanations/details. – Badda Jun 09 '17 at 09:21
  • 1
    Since `getline()` is POSIX, a feature test macro may be needed to enable its use on some systems; this detail may be worth adding to the answer. Additionally, `getline()` returns `-1` when end-of-file is reached, so your second example will not work as expected. – ad absurdum Jun 09 '17 at 10:08
  • "Unfortunately no version of C implements `getline()`."-- glibc contains `getline()`. – ad absurdum Jun 09 '17 at 11:27