Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Reading from a file and storing in array

Tags:

c

random

I've written the following program to read line by line from a file and store it in the words array. The output should be two random words from the array. But surprisingly the words array contains only the last word read repeatedly. Any help on what went wrong?

int main(){
 int i = 0;
 char line_buffer[BUFSIZ];
 char* words[20];
 FILE *fp = fopen("input.txt", "r");
  while (fgets(line_buffer, sizeof(line_buffer), fp)) {
  //printf("%s", line_buffer); 
  words[i] = line_buffer;
  i = i + 1;
 } 
 printf("%d", i);
 int j = rand()%8;
    int k = (j+1)%8;
 printf("%s %s", words[j], words[k]); 
 fclose(fp);
 return 0;
}

input.txt

nematode knowledge
empty bottle
nevertheless
claustrophobia
metamorphosis
acknowledgement
impossibility
never gave up
like image 746
razor35 Avatar asked Nov 21 '10 08:11

razor35


2 Answers

You read each line of data into the same buffer, so the last line overwrites all previous lines. You're going to have to allocate space for each line by some means or other - either dynamic memory allocation with malloc() (or possibly strdup()), or using a fixed size array (which limits the amount of data your program can handle safely). You'll also need to deal with newlines in the data read.

You get some credit for using fgets() and not using gets(); that is a 100% correct decision.


#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>

enum { MAXLINES = 30 };

int main(void)
{
    int i = 0;
    char lines[MAXLINES][BUFSIZ];
    FILE *fp = fopen("input.txt", "r");

    if (fp == 0)
    {
        fprintf(stderr, "failed to open input.txt\n");
        exit(1);
    }
    while (i < MAXLINES && fgets(lines[i], sizeof(lines[0]), fp))
    {
        lines[i][strlen(lines[i])-1] = '\0';
        i = i + 1;
    }
    fclose(fp);
    printf("%d\n", i);
    srand(time(0));
    int j = rand() % i;
    int k = (j+1) % i;
    printf("%s %s\n", lines[j], lines[k]); 
    return 0;
}

This checks that the file was opened successfully, closes the file as soon as the reading is complete, and ensures that it does not trigger a stack overflow by reading more lines than the array can hold. It wastes a lot of space by over-allocating space so each line could be very long (though the lines are typically quite short). If a line is longer than BUFSIZ, it will be read into a couple of adjacent entries in lines. It does not assume that there are 8 lines in the data file. It zaps the newline at the end of each line (unless a line is split, in which case it zaps the last character before the split on the first of the two lines). It seeds the random number generator with the current time. It seems odd that you only ever want adjacent lines from the file.

like image 92
Jonathan Leffler Avatar answered Sep 29 '22 09:09

Jonathan Leffler


int main(){
 int i = 0;

 int BUFSIZE = 1000;
 char* words[20];
 FILE *fp = fopen("input.txt", "r");
 if (fp == 0){
        fprintf(stderr, "Error while opening");
        exit(1);
 }

 words[i] = malloc(BUFSIZE);
  while (fgets(words[i], BUFSIZE, fp)) {
        i++;
        words[i] = malloc(BUFSIZE);
 } 
 printf("Output: \n");
 srand(time(NULL));
 int j = rand()%i;
 int k = (j+1)%i;
 fflush(stdout);
 printf("%d - %s %d -%s", j, words[j], k, words[k]); 

 int x;
 for(x = 0; x<i; x++)
       free(words[x]);
 scanf("%d", x);
 fclose(fp);
 return 0;
}

ps. Check malloc result

like image 26
SuperJulietta Avatar answered Sep 29 '22 07:09

SuperJulietta