我正在尝试用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;到左边的一个节点。 当我尝试将单词添加到向量时,它在递归时出现问题。
我想知道我的指针是否有问题,或者我是否以某种方式错误地传递了值。有什么想法吗?
答案 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