4

Im trying to work with the example in the K and R book for this topic, but struggling.

I want an array of Char Arrays, whereby each element of the 'Father' Array points to an array of characters (string). Basically, I am reading from a file, line at a time, storing each line into an array, and then trying to store that array, into another array, which I can then sort via qsort.

But I can't seem to get anywhere with this! Anyhelp on my code is much appreciated, i.e. where to go from where I am!

EDIT: The problem is, the printing function isn't printing out my words that should be within the array of arrays, instead its just printing garbage, the main problem is, I'm not sure whether i am de-referencing things correctly, or not at all, whether I am adding it to the array of arrays correctly etc.

Regards.

#define MAXLINES 5000 /* max no. lines to be stored */
#define MAXLEN 1000 /* max length of single line */

char *lineptr[MAXLINES];

void writelines(char *lineptr[], int nlines);

int main(int argc, char *argv[]) {
 int nlines = 0, i, j, k;
 char line[MAXLEN];
 FILE *fpIn;
 fpIn = fopen(argv[1], "rb");
 while((fgets(line, 65, fpIn)) != NULL) {
     j = strlen(line);
     if (j > 0 && (line[j-1] == '\n')) {
         line[j-1] = '\0';
     }
     if (j > 8) {
         lineptr[nlines++] = line;
     }
 }  
 for(i = 0; i < nlines; i++)
     printf("%s\n", lineptr[i] );
return 0;    
}
2
  • You've posted some code, but you haven't said what the problem is. A compiler error message? A runtime crash? Wrong results? Something else? Commented Dec 29, 2011 at 0:43
  • 1
    Ok, the next step is to simplify the problem. Write a simpler program to confirm you have the file reading correct. Then write a separate simpler program to perform a sort. Once you have both of those working, then integrate them. Commented Dec 29, 2011 at 0:47

2 Answers 2

5

A problem is that line[MAXLEN] is an automatic variable, and so each time through the while loop it refers to the same array. You should dynamically allocate line each time through the while loop (line = calloc(MAXLEN, sizeof(char)) before calling fgets). Otherwise fgets always writes to the same memory location and lineptr always points to the same array.

Sign up to request clarification or add additional context in comments.

5 Comments

That line memory would need to be allocated each time I read a line though, so I would need that in some sort of loop as well?
Yes. That should be the first thing in the while loop. Then use fgets, then check for NULL and break out
calloc with MAXLEN is overkill. lineptr[nlines++] = strdup(line); would be sufficient.
he can directly use lineptr[i] and not use line at all. using line in this case disturbs the comprehension.
Really unsure where to start if Im honest :(
4

Dan definitely found one error, the identical storage. But I think there are more bugs here:

while((fgets(line, 65, fpIn)) != NULL) {

Why only 65? You've got MAXLEN space to work with, you might as well let your input be a bit longer.

    j = strlen(line);
    if (j > 0 && (line[j-1] == '\n')) {
        line[j-1] = '\0';
    }
    if (j > 8) {
        lineptr[nlines++] = line;
    }
}

Why exactly j > 8? Are you supposed to be throwing away short lines? Don't forget to deallocate the memory for the line in this case, once you've moved to the dynamic allocation that Dan suggests.

Update

ott recommends strdup(3) -- this would be easy to fit into your existing system:

while((fgets(line, 65, fpIn)) != NULL) {
    j = strlen(line);
    if (j > 0 && (line[j-1] == '\n')) {
        line[j-1] = '\0';
    }
    if (j > 8) {
        lineptr[nlines++] = strdup(line);
    }
}

Dan recommended calloc(3), that would be only slightly more work:

line = calloc(MAXLINE, sizeof char);
while((fgets(line, 65, fpIn)) != NULL) {
    j = strlen(line);
    if (j > 0 && (line[j-1] == '\n')) {
        line[j-1] = '\0';
    }
    if (j > 8) {
        lineptr[nlines++] = line;
    line = calloc(MAXLINE, sizeof char);
    }
}

Of course, both these approaches will blow up if the memory allocation fails -- checking error returns from memory allocation is always a good idea. And there's something distinctly unbeautiful about the second mechanism.

2 Comments

I am working with WPA words, thus between 8 and 63 characters :)
Really unsure where to start if Im honest :(

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.