How to return a random line from a text file using "C"?

Presuming I have this in a test.txt file:

1
2
3
4
5
1
2
3
4
5


And return a random number from the file:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
void retrieveRand()
{
    FILE *file;
    char fname[MAX] = "strings.txt";
    int line;

    file = fopen(fname, "r");

    for(char buff[256] = {0}; fscanf(file, "%d", &line) != EOF && fgets(buff, 255, file) != NULL; line++);

    fclose(file);

    int r = rand() % line;

    if(r == 0)
    {
        printf("\n\n   %d", sizeof(r) + 1);
    }
    else
        printf("\n\n   %d", r);

    printf("\n\n   Press any key to return..");
    _getch();
}


.. and I get a random numbers each time the code is executed, even if is the same routine.. (by routine I mean.. if I run program again same numbers will be shown and will not begin differently for example if I run once the program is showing 4, 3, 5, 3, 1... second time numbers are random but the same start 4, 3, 5, 3, 1....), which I suppose I have to use the srand() function to generate different every time the program is running.

This said.. all goog, but how do I print a random line if the test.txt looks like this:

1
2
3
4
5
1 Hello world
2 Outside is raining
3 Nothing else matters
4 Good evening
5 Hello again


..without printing the numbers in front?
Last edited on
My code above return just 1 number and not like my example 4, 3, 5, 3, 1.... I showed that example because the function is used in my code.. so if I call the function repetitive I get all those numbers. And if closing the program and ran again calling that function will give me same result, I mean different random numbers but exactly like the first ones 4, 3, 5, 3, 1....
you need to know how many lines you have total. you look like you try to read this from the file; is it giving the right amount?
anyway, what you have looks close, you need logic like one of these 2:

get number of lines total
generate random line number
for(random line number, read a line)
the last line read is your random line.

or
read all the lines into an array of strings (2-d char array, for example)
get a random line
return the random line from the array.
this is much more efficient.

what bothers me in your code
line++ ?? you read the number of lines, then increment it?
you only read a 1-d array of lines, so you read a line and discard it each time, if I read that right (My C is rusty )
and I have no idea what you are trying to print there. Its not a line from the file.

and I could be wrong in what I said on the errors, again, I am rusty.
Last edited on
C Exercises: Read the file and store the lines into an array - https://www.w3resource.com/c-programming-exercises/file-handling/c-file-handling-exercise-4.php

Once you know the number of lines in the file selecting which line to output at random becomes a trivial exercise. The clamping criteria becomes:
1
2
3
4
5
6
7
8
9
int total_lines;
int ran_line;
...
/* code to read each line in the file and stuff it into the array, 
    counting each line read and stored */
...
ran_line = rand() % total_lines
...
/* code to output the selected line */

The file has, for example, 50 lines of data. You want a random number between 0 and 49.
.. Ahh Okay I got it. I'll try to do my best, and come back with the problem solved.
I thank you all for your contribution, your hint may be the right one.
same numbers will be shown and will not begin differently for example


Have you used the srand function at the beginning of the program to seed the random number generator?
No seeplus, I added after srand(time(NULL)); and now generates different numbers.
I read about the https://www.w3resource.com/c-programming-exercises/file-handling/c-file-handling-exercise-4.php as Furry Guy mentioned, and I understand the concept of reading and storing the file in to an array, still I have same question; I'm getting the random lines as I used rand() after storing lines in to the array but can't figure out how to NOT print the integers in the front of it.

The problem is that from this file.txt:

1
2
3
4
5
1 Hello world
2 Outside is raining
3 Nothing else matters
4 Good evening
5 Hello again


.. the result output when use rand() is:

 
2 Outside is raining


but I just want to print only what's after the integer NOT incude it like this:

 
Outside is raining
this is the code modified to read, store in to array and print it randomly:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
void retrieveRand()
{
    FILE *file = NULL;
    char line[LSIZE][RZISE];
    char fname[MAX] = "strings.txt";
    int i = 0;
    int tot = 0;

    file = fopen(fname, "r");

    srand(time(NULL));

    while(fgets(line[i], LSIZE, file))
    {
        line[i][strlen(line[i]) - 1] = '\0';
        i++;
    }
    tot = rand() % i;

    printf("   %s", line[tot]);

    printf("\n\n   Press any key to return..");
    _getch();
}


where LZISE is 128 MAX is 1000
and RZISE is 50
defined in my code
Last edited on
Consider:

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
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
#include <string.h>

#define LSIZE 128
#define RSIZE 50
#define MAX 1000

int main()
{
	const char fname[MAX] = "strings.txt";
	FILE* file = fopen(fname, "r");

	if (file == NULL) {
		puts("Cannot open file");
		return 1;
	}

	char line[LSIZE][RSIZE];
	int tot = 0;

	srand(time(NULL));

	for (; tot < LSIZE && fscanf(file, "%*d ")!= EOF && fgets(line[tot], RSIZE, file); ++tot)
		line[tot][strlen(line[tot]) - 1] = '\0';

	printf("%s\n", line[rand() % tot]);
}

:D Yep that's working.. thanks alot for your answer seeplus. Still I wander what does this format scan "%*d". Is it.. for not storing it in to a variable ?
Last edited on
Ahh okay.. understand now .. just to ignore it.. and then print whatever is after. Okay got it
Thanks again and cheers :)
Topic archived. No new replies allowed.