结构中向量的问题

时间:2014-09-29 00:00:11

标签: c++ pointers vector struct tree

我正在尝试用C ++创建一个三元树,它会读取一个文件并根据它读取的单词创建树。每个节点都有一个字符,然后是文件中以该字符开头的所有单词的列表,父指针,left1指针,left2指针和右指针。

现在,我的程序将构建一个树,如果它每个类型最多只有一个节点(右,左1,左2)但是当我尝试使用recurtion,并在单词向量中添加一个单词时,它给了我错误说"总线错误:核心转储"

#include <iostream>
#include <fstream>
#include <iomanip>
#include <string>
#include <vector>
#include <ctype.h>
using namespace std;
struct node_t{
    node_t *parent;
    node_t *left1;
    node_t *left2;
    node_t *right;
    char letter;
    vector<string> wordList;
    int lineCount;
};
int buildTree(ifstream &dataFile, node_t *root);
int insertWord(ifstream &dataFile, node_t *parent, char myLetter);
node_t buildRoot(ifstream &dataFile);
string getWord(ifstream& dataFile, node_t& root);


int main( int argc, char *argv[] ) {
    //check for valid number of command args
    if(argc !=2 ){
        cout << "Error: invalid amount of arguments. Usage: " << argv[0] << " <filename>\n";
        return 0;
        }
    else{
        ifstream dataFile;
        char *fileName;
        fileName = argv[1];
        strcat(fileName, ".dat");

        //attempt to open file
        dataFile.open(fileName, ios::in);
        if(!dataFile){
             cout << "Error: Cannot open file.\n";
             return 0;
        }
         else{
            node_t root;
            root = buildRoot(dataFile);
            if(root.wordList[0] == "1"){
                return 0;
            }
            else if(buildTree(dataFile, &root) == 1){
                return 0;
            }
            else{
                for(int i = 0; i < root.wordList.size(); i++){
                    cout << root.wordList[i] << " ";
                }
            cout << endl;
                if(root.right != NULL){
                cout << "Right node does not equal null" << endl;
                }
                cout << endl;
                if(root.left1 != NULL){
                cout << "Left1 node does not equal null" << endl;
                }
                cout << endl;
                if(root.left2 != NULL){
                cout << "Left2 node does not equal null" << endl;
                }
                cout << endl;
            dataFile.close();
            }
          return 0;
        }
    }
}

int buildTree(ifstream &dataFile, node_t *root){
    char ch;
    dataFile.get(ch);
    while(!dataFile.eof()){
        while((isspace(ch) || ch == '\n') && !dataFile.eof()){
                if(ch == '\n'){
                root->lineCount++;
            }
            dataFile.get(ch);
            if(dataFile.eof()){
            return 0;
            }
        }
        if(!isalpha(ch)){
            cout << "Error: On line " << root->lineCount << ", " << ch << " is not a letter.";
            return 1;
        }
        else{
            if(insertWord(dataFile, root, ch)== 1){
                return 1;
            }
            dataFile.get(ch);
        }
    }
    return 0;
}

我的下一个功能很长,所以我只发布一部分内容:

int insertWord(ifstream &dataFile, node_t *root, char ch){

//if the letter node already exists or is equal to the root letter
    if(tolower(ch) == tolower(root->letter)){
        string word;
        string firstLetter = string(1, ch);
        word = firstLetter;
        dataFile.get(ch);
        while(!isspace(ch) && ch != '\n'){
            if(!isalpha(ch)){
                cout << "Error: On line " << root->lineCount << ", " << ch << " is not a letter.";
                return 1;
            }
            else{
                word = word + ch;
                dataFile.get(ch);
            }
        }
        if(ch == '\n'){
            root->lineCount++;
        }
        int wordCheck = 0;
        for(int i = 0; i < root->wordList.size(); i++){
            if(root->wordList[i] == word){
                wordCheck = 1;
            }
        }
//***This is where the error occurs in the recursion
        if(wordCheck != 1){
            root->wordList.push_back(word);
        }
            return 0;
    }
//if letter is less than root letter
    if(tolower(ch) < tolower(root->letter)){
    //if there is no left1 node, create and initialize one
        if(root->left1 == NULL){
            node_t left1Node;
            root->left1 = &left1Node;
            left1Node.parent = root;
            left1Node.left1 = NULL;
            left1Node.left2 = NULL;
            left1Node.right = NULL;
            left1Node.letter = ch;
            string firstLetter = string(1, ch);
            left1Node.wordList.push_back(firstLetter);
    //Add word to left1 node
            string word = firstLetter;
            dataFile.get(ch);
            while(!isspace(ch) && ch != '\n'){
                if(!isalpha(ch)){
                    cout << "Error: On line " << root->lineCount << ", " << ch << " is not a letter.";
                    return 1;
                }
                else{
                    word = word + ch;
                    dataFile.get(ch);
                }
            }
            if(ch == '\n'){
                root->lineCount++;
            }
            left1Node.wordList.push_back(word);
            return 0;
        }
    //if there is a left1 but no left 2
        else if(root->left2 == NULL){
    //if new letter is = left1
        if(tolower(ch) == tolower(root->left1->letter)){
            if(insertWord(dataFile,root->left1, ch) == 1){
                return 1;
            }
            else{
                return 0;
            }
        }

我一直在测试它的文件有&#34; Dog Cat Cake&#34; 所以它应该创建根节点,left1节点,然后尝试添加&#34; Cake&#34;到左边的一个节点。 当我尝试将单词添加到向量时,它在递归时出现问题。

我想知道我的指针是否有问题,或者我是否以某种方式错误地传递了值。有什么想法吗?

1 个答案:

答案 0 :(得分:0)

这非常狡猾:

ifstream dataFile;
char *fileName;
fileName = argv[1];
strcat(fileName, ".dat");

//attempt to open file
dataFile.open(fileName, ios::in);

您正在做的是覆盖您的程序参数。这可能会导致各种隐藏的问题。

为什么不在那里使用std::string

std::string fileName = argv[1];
fileName += ".dat";
ifstream dataFile(fileName.c_str()); // no need to say ios::in because its an ifstream()

另外,非常危险,您正在为指针分配自动变量的地址。当自动变量超出范围时,它们将被销毁。

所以这里:

//if there is no left1 node, create and initialize one
    if(root->left1 == NULL){
        node_t left1Node; // ALERT!! This variable will be destroyed automatically very soon!!!
        root->left1 = &left1Node;

您需要创建如下动态变量:

//if there is no left1 node, create and initialize one
    if(root->left1 == NULL){
        root->left1 = new node_t; // dynamically created, YOU decide when to destroy it