简体   繁体   中英

C fgets() only handling last line

I am trying to write a program that takes in a .txt file, reads all the lines, then stores each word into a BST. I then perform an inorder traversal to print the words in alphabetical order. The program works perfectly if the text file contains only 1 line, but if the text file has more than 1 line there are unexpected results.

Example: the text file:

first line
second line

Outputs only:

line
second

Completely losing the first line of the text file.

My main method is:

#define MAX_STR_LEN 1024
int main(int argc, char** argv)
{
  FILE *fptr;
  fptr = fopen(argv[1], "r");

  if(fptr == NULL)
  {
   printf("Error. Could not open file.\n");
   exit(1);
   }

  char line[MAX_STR_LEN];
  char* tok;
  struct BSTnode* theRoot;
  int isRoot = 1;

  while(fgets(line, MAX_STR_LEN, fptr) != NULL)
  {
    tok = strtok(line, " \n");


    while(tok != NULL)
    {
      if(isRoot == 1)
      {
        theRoot = createNode(tok); //creates the root for the BST
         isRoot = 0;
      }
      else
      {
           processStr(&theRoot, tok); //places a new word into the BST
      }

      tok = strtok(NULL, " \n");
    }

  }

  inorder(theRoot); //prints words alphabetically
  fclose(fptr);
  return 0;
}

I stepped through with GDB and when fgets is called for the second time in the while loop, theRoot of the BST is changed and overwritten. Any advice would be appreciated.

EDIT:

struct BSTnode* createNode(char* word) 
{
    struct BSTnode* temp = malloc(sizeof(struct BSTnode));
    temp->word = word;
    temp->left = NULL;
    temp->right = NULL;
    return temp;
}

void processStr(struct BSTnode** root, char* word) 
{
    struct BSTnode** node = search(root, word);
    if (*node == NULL) {
        *node = createNode(word);
    }
}

struct BSTnode** search(struct BSTnode** root, char* word) {
    struct BSTnode** node = root;
    while (*node != NULL) {
        int compare = strcasecmp(word, (*node)->word);
        if (compare < 0)
            node = &(*node)->left;
        else if (compare > 0)
            node = &(*node)->right;
        else
            break;
    }
    return node;
 }

You need to duplicate the word in your createNode() , try something like:

struct BSTnode* createNode(char* word) 
{
    struct BSTnode* temp = malloc(sizeof(struct BSTnode));
    temp->word = malloc(strlen(word) + 1);
    strcpy(temp->word, word);
    temp->left = NULL;
    temp->right = NULL;
    return temp;
}

In your createNode() , word is a pointer to substring in line , another call to fgets() will overwrite the content of this array.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM