0

I have a homework task that requires me to process .txt files by scanning them into a flexible data structure and then searching the files for words with capital letters. I'm having issues scanning them in this flexible data structure I'm using. The reason that the data structure needs to be flexible is that it needs to be able to process any .txt files.

The data structure I want to use is an array that points to arrays that contains the content of the line. I'm open to using a different structure if it's easier.

I've tried to scan it in line by line using fgets, and using malloc to allocate just enough to store the line, but it doesn't seem to work.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define STEPSIZE 100

int main()
{
    FILE *inputFile;

    //Opens the file in read mode
    inputFile = fopen("testfile.txt", "r");

    //Error message if file cannot open
    if (inputFile == NULL)
    {
        printf("Unable to open file");
        return 1;
    }

    int arrayLen = STEPSIZE;

    // Allocate space for 100 lines. The **lines is the data structure used to store all the lines

    char **lines = (char **)malloc(STEPSIZE * sizeof(char*));

    char buffer[3000];

    int i = 0;

    while (fgets(buffer, 3000, inputFile))
    {

        //Checks if the array is full, and extends it
        if(i == arrayLen)
        {
            arrayLen += arrayLen;
            char ** newLines = realloc(lines, 200 * sizeof(char*));
            if(!newLines)
            {
                printf("cant realloc\n");
            }
            lines= newLines;
        }


        // Get length of buffer
        int lengthOfBuffer = strlen(buffer);

        //Allocate space for string. The +1 is for the terminating character
        char *string = (char *)malloc((lengthOfBuffer + 1) * sizeof(char));

        //copy string from buffer to string
        strcpy(string, buffer);

        //Attach string to data structure
        lines[i] = string;

        //Increment counter
        i++;
        printf("%s", lines[i]);
    }

    //Closes the file
    fclose(inputFile);


    for (int j = 0; j < 100; j++){
        printf("%s \n", lines[i]);
    }

    return 0;
}

When the final for loop runs, ideally the contents of the file gets printed, just to show that it has been stored and is able to be processed, but currently i get exit code 11.

Any help would be appreciated.

jzpearson
  • 15
  • 1
  • What happens when you try to print line 96 if there are only 12 lines in the file? – Andrew Henle May 20 '19 at 14:50
  • 1
    Why wouldn't you just get the size of the file then allocate the memory needed for it before you read it? Looks here: https://stackoverflow.com/questions/238603/how-can-i-get-a-files-size-in-c once you have the size of the file then call malloc and read into the buffer. And your code isn't freeing any memory allocated. – Irelia May 20 '19 at 14:52
  • This code has magical constants everywhere – klutt May 20 '19 at 15:16
  • @Nina it's probably an exercise and he was equired to do like this. – Jabberwocky May 20 '19 at 15:23

1 Answers1

0

There is a problem is here:

//Increment counter
i++;
printf("%s", lines[i]);    // you're printing the next file that does not yet exist

Correct code:

printf("%s", lines[i]);
//Increment counter
i++;

And another one here:

for (int j = 0; j < 100; j++) {  // your loop variable is j
  printf("%s \n", lines[i]);     // but you use i here.
}

Correct code:

for (int i = 0; i < 100; i++) {
  printf("%s \n", lines[i]);
}

And still another one here:

  arrayLen += arrayLen;
  char ** newLines = (char**)realloc(lines, 200 * sizeof(char*));
  // here the new length of your array is inconditionally 200
  // but actually the new array length is arrayLen 

Correct code:

  arrayLen += arrayLen;
  char ** newLines = (char**)realloc(lines, arrayLen * sizeof(char*));

There may be more problems though, I didn't check everything.

BTW: sizeof(char) is 1 by definition, so you can just drop it.

BTW2: arrayLen += arrayLen; are you sure this is what you want? You double the size of your array each time. This is not necessarily wrong but using this method the array length will very quickly grow to a very big number. You probably wanted this: arrayLen += STEPSIZE;

BTW3:

while (fgets(buffer, 3000, inputFile))

this is not actually wrong, but you'd better write this:

while (fgets(buffer, sizeof buffer, inputFile))

which eliminates one of the two hard coded constants 3000.

BTW4: at the end you only print the first 100 lines yo've read. You should be able to correct this yorself.

BTW5: you should also free all the memory you have allocated. I leave this as an exercise to you. Hint: it's about three lines of code to add at the end of main.

Jabberwocky
  • 48,281
  • 17
  • 65
  • 115