2017-12-18 186 views
0

對於我的C類的作業,我們被要求從標準輸入讀取數據,將這些字連同它們的位置(線和偏移量)一起放入二進制樹中,修改二叉樹,並根據位置在文件中打印二叉樹。我在那裏(我希望),但我遇到了問題,我的新數據一直覆蓋我的舊數據 - 特別是,當我將它放入Insert數組時,新的Insert結構會覆蓋舊的Insert結構,這意味着我的數組中有幾個相同的條目。我不太清楚如何阻止它的發生,甚至是爲什麼發生這種情況,儘管我認爲這可能是因爲我將數據寫入同一個指針而沒有清除它。新數據覆蓋指針中的舊數據

公平的警告:我們大部分時間都是在這個學期留給自己,我的代碼看起來很錯,我很驚訝它的工作原理。

#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 
#define s 5000 
#define z 10 

struct Position { 
    int line; // line number 
    int offset; // 1, 2, 3, ...: 1st, 2nd, 3rd, ... word on the line 
    struct Position *next; 
}; 

struct TreeNode { 
    char *word; 
    struct Position *positions; // store positions where the word occurs 
    struct TreeNode *parent; 
    struct TreeNode *left; 
    struct TreeNode *right; 
}; 

struct Insert { 
    char *word; 
    struct Position *pos; 
}; 

struct RemoveWord { 
    char *word; 
}; 

struct RemovePos { 
    struct Position *pos; 
}; 

struct TreeNode *createNode(char *word, struct Position *pos) { 
    struct TreeNode *node = (struct TreeNode*) malloc(sizeof(struct TreeNode)); 
    node->word = malloc(s); 

    strcpy(node->word, word); 
    node->positions = pos; 
    node->parent = node->left = node->right = NULL; 

    return node; 
} 

struct Position *createPos(int line, int offset, struct Position *next) { 
    struct Position *node = (struct Position*) malloc(sizeof(struct Position)); 
    node->line = line; 
    node->offset = offset; 
    node->next = next; 

    return node; 
} 

struct TreeNode *insertNode(struct TreeNode* tree, char *word, struct Position *pos) { 
    struct Position *tpos = (struct Position*) malloc(sizeof(struct Position)); 


    if (tree == NULL) { 
     return createNode(word, pos); 
    } 
    if (strcmp(word, tree->word) < 0) { 
     tree->left = insertNode(tree->left, word, pos); 
    } else if (strcmp(word, tree->word) > 0) { 
     tree->right = insertNode(tree->right, word, pos); 
    } else if (strcmp(word, tree->word) == 0) { 
     tpos = tree->positions; 
     while(1) { 
      if (tpos->next == NULL) { 
       tpos->next = pos; 
       break; 
      } 
      tpos = tpos->next; 
     } 
    } 

    return tree; 
} 

struct TreeNode *min(struct TreeNode* tree) { 
    struct TreeNode* c = tree; 

    while (c->left != NULL) { 
     c = c->left; 
    } 

    return c; 
} 

struct TreeNode *removeWord(struct TreeNode* tree, char *word) { 
    if (tree == NULL) { 
     return tree; 
    } 

    if (strcmp(word, tree->word) < 0) { 
     tree->left = removeWord(tree->left, word); 
    } else if (strcmp(word, tree->word) > 0) { 
     tree->right = removeWord(tree->right, word); 
    } else { 
     if (tree->left == NULL) { 
      struct TreeNode *temp = tree->right; 
      free(tree); 
      return temp; 
     } else if (tree->right == NULL) { 
      struct TreeNode *temp = tree->left; 
      free(tree); 
      return temp; 
     } 

     struct TreeNode *temp = min(tree->right); 

     strcpy(tree->word, temp->word); 

     tree->right = removeWord(tree->right, temp->word); 
    } 

    return tree; 
} 

struct TreeNode *removePosition(struct TreeNode *tree, struct Position *pos) { 
    if (tree == NULL) { 
     return tree; 
    } 

    removePosition(tree->left, pos); 

    if (tree->positions->line == pos->line && tree->positions->offset == pos->offset) { 
     tree = removeWord(tree, tree->word); 
     return tree; 
    } 
    while(1) { 
     tree->positions = tree->positions->next; 
     if (tree->positions == NULL) { 
      break; 
     } 
     if (tree->positions->line == pos->line && tree->positions->offset == pos->offset) { 
      tree = removeWord(tree, tree->word); 
      return tree; 
     } 
    } 

    removePosition(tree->right, pos); 

    return tree; 
} 

struct TreeNode *removeLine(struct TreeNode *tree, int line) { 
    if (tree == NULL) { 
     return tree; 
    } 

    removeLine(tree->left, line); 

    if (tree->positions->line == line) { 
     tree = removeWord(tree, tree->word); 
     return tree; 
    } 
    while(1) { 
     tree->positions = tree->positions->next; 
     if (tree->positions == NULL) { 
      break; 
     } 
     if (tree->positions->line == line) { 
      tree = removeWord(tree, tree->word); 
      return tree; 
     } 
    } 

    removeLine(tree->right, line); 

    return tree; 
} 


//TESTING INORDER -- via sreekar2307 on github 
void inorder(struct TreeNode* root) { 
    if(root==NULL) return ; 
    inorder(root->left); 
    printf("word is %s, line is %i, offset is %i\n",root->word, root->positions->line, root->positions->offset); 
    while(1) { 
     root->positions = root->positions->next; 
     if (root->positions == NULL) { 
      break; 
     } 
     printf("---> addition: line is %i, offset is %i\n", root->positions->line, root->positions->offset); 
    } 
    inorder(root->right); 
} 

int main() { 
    FILE *out; 

    char line[s]; 
    int w = 1; 
    int l = 1; 
    int b = 1; //switch for before/after END 
    int I = 0; //switch for insert 
    int R = 0; //switch for remove word 
    int RL = 0; //switch for remove line 
    int INSERT = 0; // number of insert commands 
    int REMOVEWORD = 0; // number of removeword commands 
    int REMOVEPOS = 0; // number of removepos commands 
    int REMOVELINE = 0; // number of removeline commands 
    char *iw = malloc(s); //holds insert word 
    int il, io; //holds insert line, offset 
    int rwl, rwo; //holds remove word line, offset 

    struct Insert* ic[z]; 
    struct RemoveWord* rwc[z]; 
    struct RemovePos* rpc[z]; 

    struct Insert *ic1 = (struct Insert *) malloc(sizeof(struct Insert)); 
    struct RemoveWord *rwc1 = (struct RemoveWord *) malloc(sizeof(struct RemoveWord)); 
    struct RemovePos *rpc1 = (struct RemovePos *) malloc(sizeof(struct RemovePos)); 

    int rlc[z]; 

    ic1->word = malloc(s); 
    rwc1->word = malloc(s); 
    rpc1->pos = (struct Position *) malloc(sizeof(struct Position)); 

    struct Position *pos = (struct Position *) malloc(sizeof(struct Position)); 
    struct Position *tpos = (struct Position *) malloc(sizeof(struct Position)); 
    out = fopen("output.txt", "w+"); 

    pos->next = NULL; 
    tpos->next = NULL; 

    struct TreeNode *ortree = NULL; 

    while (fgets(line, s, stdin)) { 
     char *word = malloc(s); 
     line[strcspn(line, "\n")] = 0; 
     for (word = strtok(line, " "); word; word = strtok(NULL, " ")) { 
      pos = createPos(l, w, NULL); 
      ortree = insertNode(ortree, word, pos); 
      w++; 
      if (strcmp(word, "END") == 0) { 
       b = 0; 
      } 
      if (l > 1 && b == 1 && I == 0 && R == 0 && RL == 0) { 
       printf("word is %s\n", word); 
       if (strcmp(word, "I") == 0) { 
        I = 1; 
        continue; 
       } else if (strcmp(word, "R") == 0) { 
        R = 1; 
        continue; 
       } else if (strcmp(word, "RL") == 0) { 
        RL = 1; 
        continue; 
       } 
      } 

      if (I == 1) { 
       iw = word; 
       I++; 
       continue; 
      } 
      if (I == 2) { 
       il = atoi(word); 
       I++; 
       continue; 
      } 
      if (I == 3) { 
       io = atoi(word); 
       tpos = createPos(il, io, NULL); 
       ic1->pos = tpos; 
       strcpy(ic1->word, iw); 
       ic[INSERT] = (struct Insert *) malloc(sizeof(struct Insert)); 
       ic[INSERT] = ic1; 
       I = 0; 
       INSERT++; 
       continue; 
      } 
      if (R == 1) { 
       int r = atoi(word); 
       if (r == 0) { 
        strcpy(rwc1->word, word); 
        rwc[REMOVEWORD] = rwc1; 
        REMOVEWORD++; 
        R = 0; 
        continue; 
       } else { 
        rwl = r; 
        R++; 
        continue; 
       } 
      } 
      if (R == 2) { 
       rwo = atoi(word); 
       tpos = createPos(rwl, rwo, NULL); 
       rpc1->pos = tpos; 
       rpc[REMOVEPOS] = rpc1; 
       R = 0; 
       REMOVEPOS++; 
       continue; 
      } 
      if (RL == 1) { 
       rlc[REMOVELINE] = atoi(word); 
       RL = 0; 
       REMOVELINE++; 
       continue; 
      } 
     } 
     l++; 
     w = 1; 
     *line = '\0'; 
    } 

    for (int n = 0; n < INSERT; n++) { 
     printf("ic[n]->word is %s\n", ic[n]->word); 
     ortree = insertNode(ortree, ic[n]->word, ic[n]->pos); 
    } 

    for (int n = 0; n < REMOVEWORD; n++) { 
     printf("rwc[n]->word is %s\n", rwc[n]->word); 
     ortree = removeWord(ortree, rwc[n]->word); 
    } 

    for (int n = 0; n < REMOVEPOS; n++) { 
     ortree = removePosition(ortree, rpc[n]->pos); 
    } 

    for (int n = 0; n < REMOVELINE; n++) { 
     ortree = removeLine(ortree, rlc[n]); 
    } 

    inorder(ortree); 

    fclose(out); 
    return 0; 
} 

輸入被要求,所以這裏是我們給出的十個文件之一。

input.1 output.out
RL 1
RL 7
R they
R Center
END
That's a slight uptick from a year ago, when a CNN poll found that 53 percent said they were dreading having to carry on such a conversation, with 43 percent saying they looked forward to such a dialogue.

"There's a sense of dread. It suggests some indigestion may be part of Thanksgiving dinner if politics come up," said Lee Miringoff, director of the Marist Institute for Public Opinion. "People you work with and go out with socially tend to share political views, but when you get to family, if politics is in the recipe, it may not taste very well."

That trepidation about broaching politics isn't coming from just one political party, but almost two-thirds of Democrats said they are, while only about half of Republicans were. (Fifty-six percent of independents also said so.)

President Trump is, unsurprisingly, a polarizing topic of potential dinner conversation. Forty-seven percent of people in the poll said they find it "stressful and frustrating" when talking with people who have a different opinion about the president than they do. (A Pew Research Center poll from June found 59 percent saying the same thing.)

+2

不要施放malloc的結果 –

+0

@MadPhysicist,只是想知道 - 爲什麼不呢?這是我老師過去要做的事情,所以我覺得這是必須的。 (如果這是互聯網可以很容易地顯示給我的東西,請隨時不要回答;一旦我解決了這個問題,我可能會自己查看它。) – greyfiel

+0

請提供**輸入** –

回答

1

我能夠通過移動我的ic1rwc1rpc1postpos初始化到它們被使用的循環,以解決上述問題。

+0

你很好解決,但注意你在'main'中也有內存泄漏。 – 4386427

+1

順便說一句 - 考慮更多的描述性變量名稱。你有很多名字變量,沒有說明它們的用途。例如'l','w','b','R'。這使得代碼難以理解和維護。 – 4386427

+0

會做什麼;感謝您的建議! – greyfiel