1

I am making a linked lists of words that appear in a file (no repeats) and the line they first appear on. I finished what I thought would be the hard part (parsing the file while keeping track of the lines), but I believe I now have a problem in one of my methods that i cant figure out how to fix. My code is in two files, but I'm only including the method with a problem in my code along with the driver. (I tried using GDB and I think I was using it wrong because it kept saying it couldn't find files and it wouldn't run. )

int main(int argc, char **argv){
file = fopen(argv[1],"r");
/*struct fileIndex *fIndex = NULL;*/ /*put this in header file??*/
fIndex = NULL;
delimiters = " .,;:!-";/*strtok chars to seperate*/
rewind(file);
int buffer = 65;
char str[buffer+1];/*where the lines are being stored*/
char *token, *cp;
int i;
int len;
while((fgets(str, buffer, file))!=NULL){/*inserting lines*/
for(i=0; i<buffer; i++){
    if(str[i]=='\n'){
    str[i]= '\0';
    break;
    }
}
len = strlen(str);
cp = xerox(str);
token = strtok(cp, delimiters);
/*if(token!=NULL)
printf("The word is %s\n", token);*/
    if(!present(fIndex, token)&&(token!=NULL)){
        insert(fIndex, i+1, token);
    }
    while(token!=NULL){
        token = strtok(NULL, delimiters);
        /*if(token!=NULL)
        printf("The word is %s\n", token);*/
        if(!present(fIndex, token)&&(token!=NULL)){
            insert(fIndex, i+1, token);
        }

    }
}
fclose(file);
struct fileIndex *root;
root = fIndex;

while(root != NULL){
printf("The string is %s and on line %d\n", root -> str, root -> lineNum);
root = root -> next;
}


free(fIndex);
free(cp);

return 0;
}







struct fileIndex *insert(struct fileIndex *head, int num, char *insert){
struct fileIndex* newnode = malloc(sizeof(struct fileIndex));
if(newnode==NULL)
exit(1);

newnode -> str = insert;
newnode -> lineNum = num;

newnode -> next = head;
return newnode;
}

EDIT: I'm also thinking a problem in my method to check if a word is already there or not. I put a print statement where it should only print if the word is going to be inserted and all of the words printed. The little loop at the end to print the list is not printing and I think it reaches NULL when it first gets there and never loops.

present(struct fileIndex* fIndex, char *findIt){/*finds if word is in structure*/
struct fileIndex* current = fIndex;
while(current!=NULL){
current = current -> next;
if(strcmpigncase(current -> str, findIt)==0){
    return current -> lineNum;
}
}
return 0;
}
0

3 Answers 3

2

The insert function returns the new list, but you aren't using the return value in your code.

The calls should look like this:

fIndex = insert(fIndex, i+1, token);

ADDENDUM:

Also, you are using token before you check if it is NULL. It should look like this:

if((token!=NULL) && !present(fIndex, token)){
    fIndex = insert(fIndex, i+1, token);
}
Sign up to request clarification or add additional context in comments.

3 Comments

I fixed this and now I get a seg fault .
Your present function is advancing the current pointer at the top of the while loop instead of at the bottom.
Thanks. I also realized the header was incorrect! I left out the return value! Should solve one of my logic problems.
2

You should always check fopen() was success.

if(file == NULL) {
printf("Error fopen");
exit(1);
}

fgets() appends null terminator, so you don't need to do that yourself.

Comments

0
file = fopen(argv[1],"r");

You forgot to check that the fopen() succeeded. Every fopen(3) should be followed by code similar to:

if (!file) {
    fprintf(stderr, "unable to open %s\n", argv[1]);
    perror(argv[0]);
    exit(EXIT_FAILURE);
}

If you can handle the error more gracefully than quitting (fall back to a default?) then you might wish to do so.

for(i=0; i<buffer; i++){
    if(str[i]=='\n'){
    str[i]= '\0';
    break;
    }

This is pretty ugly. You don't need to null-terminate yourself, but if you wish to delete the newline then you should also make sure you're counting the newlines for your line numbers...

struct fileIndex *root;
root = fIndex;

while(root != NULL){
    printf("The string is %s and on line %d\n", root -> str, root -> lineNum);
    root = root -> next;
}


free(fIndex);
free(cp);

I never actually saw fIndex allocated -- it is just a pointer, and you assigned it NULL at the start. This entire section of code looks tacked on, and the lack of proper indentation and surrounding context makes it nearly impossible to understand. I have to think that you should separate all this code into their own routines, test them thoroughly using hard-coded tests, and make sure that it works perfectly before trying to hook it up into the larger program. (Which actually goes for the first portion, as well -- it looks like it would benefit from some isolated and directed testing.)

1 Comment

I was trying to test that it was actually making the list with the print loop.

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.