0

when i debug this C code, the code is used to read text from txt file and save to the binary tree, the variable 'x' do not create new after a loop, and it stills save the variable of the previous loop to use in the next loop,so sometime in some case it make the duplicate values at the end of while loop. i use Visual Studio 2013 to code sorry for my bad english.

void createtree(btree &t)
{
    initbtree(t);
    FILE*f;
    f = fopen("input.txt", "r");
    while (!feof(f))
    {
        data x;
        fgets(x.word, 20, f);
        x.word[(strlen(x.word) - 1)] = '\0';
        fgets(x.mean, 20, f);
        if (x.mean[strlen(x.mean)-1] == '\n')
            x.mean[(strlen(x.mean) - 1)] = '\0';
        tnode*p = createtnode(x);
        insertnode(t.root, p);
    }
    fclose(f);
    printf("Create Tree done!\n");
}

3 Answers3

0

each fgets will get another line.

So I believe you should not use two fgets in your loop in the following codes

fgets(x.word, 20, f);
x.word[(strlen(x.word) - 1)] = '\0';
fgets(x.mean, 20, f);
Ken Lee
  • 6,985
  • 3
  • 10
  • 29
0

the variable 'x' do not create new after a loop

You do not initialize 'x', therefore it can contain whatever was on the stack at that particular address.

And in particular, apart from the first time through the loop, what will at that particular address will likely be what was left there by the previous execution of the loop.

If you want 'x' initialized, initialize it.

a guest
  • 462
  • 3
  • 5
  • i use ```data x``` to create x, data is a struct i create to save a word and its mean ```struct data { char word[20]; char mean[20]; }; ``` – ngochieu2004 Dec 10 '20 at 03:28
  • when i read file with the last line with no character,it only \n, normal it will save null to x, it still save the previous values and use it to add on the tree before end the loop, so it make the duplicate value in the tree. – ngochieu2004 Dec 10 '20 at 03:42
  • OK, not just saying `data x` does not initialize `x` - the content of the structure is undefined. But I think that is not your problem now. – a guest Dec 10 '20 at 13:15
0

You do not check the return status from fgets(), so you cannot know if there is a read error or end-of-file is reached.

Suppose the EOF indicator is not set. You attempt an fgets call and it now discovers that the stream has reached the end of the file. At that point:

  1. the EOF indicator is set
  2. nothing is written to the output string
  3. the fgets call returns null

Since you don't check the return, and the output string contains what it did before, you will create a duplicate node.

The key information here is that feof() will not return true until after fgets() has encountered an end of file. Correct handling is to detect the null return from fgets(), and then use feof() or ferror() to determine the reason for the null return.


Code structure should be like:

data x;
while (fgets(x.word, 20, f) && fgets(x.mean, 20, f)) {
      ... process new value of x here as before ...
}

if (!feof(f)) 
  ... something bad happened, not legitimate EOF ...
a guest
  • 462
  • 3
  • 5