Print lines from text file after user pressing enter

I'm writing a 'read file and print line' program described below.
1. Accept user input for filename and number of lines from command line.
e.g. File1.txt 3
2. Print the first group of 3 lines.
3. User presses enter. Print next group of 3 lines.
4. If last group is less than 3 lines, print it all.

I'm able to complete requirements 1 and 2, but not 3 and 4. Here is my code. I understand 'char ch=fgetc(stdin)'; ch=='\n' means enter key's pressed. But I'm struggling how to incorporate these in my program. Please advise. Thank you.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
#include <stdio.h>
#include <stdlib.h>

int main(int argc, char * argv[])
{
    FILE* fp;             // file pointer
    char* line = malloc(255);
    int bufferLength = 255;

    int cnt = 0;

    //I omit errors checking here because it is not my problem

    // read lines from file one by one
    while (fgets(line,bufferLength, fp))
    {
        cnt++;
        if ( cnt > atoi(argv[2]) )
            break;

        printf("%s",line);
        fflush(stdout);
    }

    char ch=fgetc(stdin);//how to incorporate this in my codes?
    if(ch=='\n')//how to incorporate this in my codes?

    fclose(fp);
    free(line);
    return 0;
}
Last edited on
I'm able to complete requirements 1 and 2, but not 3 and 4

Where are you trying to "get" the file name and number of lines from the command line? Normally when talking about getting something from the command line you use the arguments of main().

What exactly does your file look like?

As far as items 3 and 4, you really need to first do items 1 and 2.

By the way why are you using malloc for line instead of just using a "normal" statically allocated array? Also why are you using fgets() to get an entire line from the file, instead of using something like fscanf(), to get individual numbers from the file.

Do you that the "break" statement exits the loop, so you will only ever print the first set of numbers?

Also what happens if you fail to provide command line arguments of the correct type to the program.

You note that you aren't showing any error checking because "that's not your problem" however I would guess that you're failing to insure that one or more of the required conditions are properly met. I suggest you show the complete program because what you're showing seems to be full of "errors".



I learnt the malloc function to allocate memory. If you have better suggestion please help correct my codes. Below is my exact program. I supplied file name and number of lines to print out in command line. It can print out first group of lines. But I don't know how to modify the program to print out next group of lines if user presses enter. And continue to print out when user presses enter again. If user presses other key, then presses enter, the program should exit. Please advise. Thank you very much.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
#include <stdio.h>
#include <stdlib.h>

int main(int argc, char * argv[])
{
    FILE* fp;             // file pointer
    char* line = malloc(255);
    int bufferLength = 255;

    int cnt = 0;

    if( argc < 3)
    {
        fprintf(stderr, "Insufficient arguments. Program terminates.");
        exit(1);
    }

    fp = fopen(argv[1],"r"); //argv[1] is filename from command line

    if( fp == NULL )
    {
        fprintf(stderr, "File not exists. Program terminates.");
        exit(1);
    }

    while (fgets(line,bufferLength, fp))
    {
        cnt++;
        if (cnt > atoi(argv[2])) //argv[2] is number of lines (e.g. 3)
            break;
        printf("%s",line); //print first 3 lines on console from the file
    }

    fclose(fp);
    free(line);
    return 0;
}
char x[255]; //no need for dynamic memory. remove malloc and free stuff.
x works just like a char pointer, eg strcpy(x, ... works fine. You should name the 255 as a constant value, though, to avoid magic numbers, eg call it linelength or something.

atoi of argv 2 is a constant, maybe pull it out one time instead of in the loop just in case the compiler is dumb. also that line (29) may be possible to combine the if statement into the while condition. None of this matters, just minor cleanup.


But I don't know how to modify the program to print out next group of lines if user presses enter.

Well the first thing you need to do is stop using the break statement since it causes the loop to end. Instead you may want to ask the user to press some key or something. But be careful with trying to use the enter key, it can be tricky to catch in some instances. I'd recommend asking the user if they want to continue and expect a 'y' or 'n' type of answer. If your user enters something other than 'y' then you could "break".

Thanks for above comments. I revised my codes below. It fulfills requirements except #4.

Recap the requirements -

1. Accept user input for filename and number of lines from command line.
e.g. File1.txt 3 ---> Codes below fulfilled.
2. Print the first group of 3 lines. ---> Codes below fulfilled
3. User presses enter. Print next group of 3 lines. ---> Codes below fulfilled
4. If last group is less than 3 lines, print it all. ---> I wrote these two lines trying to fulfill this requirement.
1
2
if (feof(inFp))
   return(EXIT_SUCCESS);

It does print rest lines but cursor is moved down. It does not stop at line ends.
On the other hand the assignment checker says it's a wrong place to check EOF.
Could anyone please advise codes for 'if no line, program finish'?
Thank you

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include <stdio.h>
#include <stdlib.h>

int main(int argc, char *argv[])
{
    FILE *inFp;
    char buf[255];

    inFp = fopen(argv[1],"r"); //argv[1] is filename

    do
    {
        for (int i = 0; i < atoi(argv[2]); i++)//argv[2] is number of lines to print
        {
            if (feof(inFp))                    //if input file reaches end
                return(EXIT_SUCCESS);          //this program ends
            fgets(buf, (int)sizeof(buf), inFp);//read line
            fputs(buf, stdout);                //write line
        }
    } while (getchar() == '\n');               //while user presses enter key

    fclose(inFp);                              //close input file
    return(EXIT_SUCCESS);
}
Ideally, you should account for the possibility that the line is longer than 254 characters.

The code is easier if you turn the logic around:
for each line
print it
if (you've reached N lines) {
pause
reset line counter
}
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
#include <cstdio>
#include <cstdlib>
#include <cstring>

using std::fopen;
using std::fgets;
using std::fwrite;
using std::getchar;
using std::fclose;
using std::strlen;

int main(int argc, char *argv[])
{
    FILE *inFp;
    int limit = atoi(argv[2]);	// # lines to print
    int count = 0;		// # lines printed
    char buf[255];

    inFp = fopen(argv[1],"r"); //argv[1] is filename
    while (fgets(buf, sizeof(buf), inFp)) {
	size_t len = strlen(buf);
	fwrite(buf, len, 1, stdout);
	if (buf[len-1] == '\n') {
	    // Contains a newline. See if you should pause
	    if (++count == limit) {
		getchar();
		count = 0;
	    }
	}
    }
    fclose(inFp);
    return 0;
}

Topic archived. No new replies allowed.