结构中的向量问题

Problems with Vector within a Struct

本文关键字:问题 向量 结构      更新时间:2023-10-16

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

现在,如果每个类型(Right,left1,left2)最多只有一个节点,我的程序就会构建一个树。但当我尝试使用递归,并在单词向量中添加一个单词时,它会给我一个错误,说"总线错误:核心转储"

#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;
            }
        }

我一直在用一个有"狗猫蛋糕"的文件测试它因此,它应该创建根节点,即left1节点,然后尝试将"Cake"添加到左侧的一个节点。当我试图将单词添加到向量中时,它在递归中出现了问题。

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

这是非常不可靠的:

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