binary tree doesn't rebuild from file - c++

I'm new on data structures and we were assigned to make a guessing game using binary tree implementation. I have accomplished the program flow without file implementation. I have saved the binary tree preorderly on an external file now I have problem in rebuilding tree from file
in my file I have:
Is it Angel Locsin?:#Neneng B?Is it Sam Pinto? ##White Beauty?Is it
Marian Rivera? ##HotandSexy?Is it Cristine Reyes? ###
The "#" is for a NULL node.
I have also my code. I follow the algorithm of what my professor gave me. I searched on the internet and gave me same algorithm as of what my prof said. My problem is on every third non-null data the program crashes. I think the main reason of crashing is a node that was not set to null after the third non-null data is inserted. If so, how could I set it to NULL so that my program will not crash.I assigned the data from file into array of strings and set a "\0" at the last index of array.
void read(node *temp)
{
while(array[j]=="#")
j++;
if(array[j]=="\0")
return;
node *nNode;
nNode = new node;
nNode->yes=NULL;
nNode->no=NULL;
nNode->data=array[j];
j++;
temp=nNode;
read(temp->yes);
read(temp->no);
}

Your problem is in the definition of your read function. I guess the idea is that "temp" is an output parameter of type "node*". But this is not what you have written.
You need to have a pointer or a reference to the "node*" parameter like e.g. so:
void read(node** temp)
Then adjust the rest of the code such that is compiles by proper (de)referencing. This should solve your crash.

Related

ROOT - pyroot: Branch seen as leaf, can't access actual leaves

I am trying to extract information from a root file using pyroot.
I tried using the usual GetBranch, GetLeaf, GetValue but it does not work as usual, so I tried alternatives.
I found an equivalent code in c++ which is extracting the values just fine from my ROOT file but when applying the same thing in pyroot, I get an empty object as my "mcinfo" (see below).
I also tried displaying the branches and leaves with GetListOfBranches() and GetListOfLeaves(). I get the proper list of branches with the first but when looking at the list of leaves (here MC but it's the same with all branches), I get out of MC.GetListOfLeaves() that the only leaf is MC too... I have several leaves (for instance energy) that I can access just fine with the c++ code and directly with data.Scan("energy") too...
Anyone has an idea of how to fix this? Sorry, I am not that familiar with ROOT yet. I assume it is a rather easy fix, but I don't see what is wrong with this...
C++ code:
TFile *file = new TFile(fname);
TTree *data = (TTree*)file->Get("data");
TBranch * McinfoBranch;
MCInfo* mcinfo = (MCInfo*)file->GetList()->FindObject("MC");
data->SetBranchAddress("MC", &mcinfo, &McinfoBranch);
pyroot version:
infile = ROOT.TFile(fname)
data = infile.Get("data")
mcinfo = infile.GetList().FindObject("MC")
which gives me this when printing mcinfo: <cppyy.gbl.TObject object at 0x(nil)>.

C++ Unable to print the entire list in a that has already been created and read from a text file

Hello I have been having trouble with my program I've created a list and I have the following program
Its goal is to Read the 5 variables inside the text file 5 variables in 5 different inputs
so I manage to correctly show the list inside the while loop since every time a line is read it's printed untill .eof(End Of File)
My goal is that I am trying to print the list OUTSIDE of the while Loop that has already read and printed those 5 variables 10x the problem is that it repeats the last entered 5 Variables in the list
I and repeats that 10x (size of the list)
I've also tried something like this inside the for loop which I found in here:
int ID=it->ID;
string NAME=it->NAME;
int SEMESTER=it->SEMESTER;
string DIRECTION=it->DIRECTION;
double GRADE=it->GRADE;
As if those are nodes but I am a starter with nodes as well as lists and it seems to have failed
When I look at the code you've provided, I see that in your for loop the a_student is used, which is not updated by/with the iterator. Basically you're not looping over the created student list.
Maybe try using std::for_each (cppreference) it will save you a lot of time:)
Godbolt example: https://godbolt.org/z/fQUhcr
The issue on the left column of code is that you are not de-referencing the iterator. You never set the a_students variable inside the loop, so why do you expect it to change on each iteration?
Write something like:
a_students = *it;
inside the loop. However there is a simpler way. Instead of manually handling the iterators, use:
for (auto a_students: s_stl_list)
{
// do something with each "a_students" which will be AUTOmatically the right type
}

dirEntries with walklength returns no files

I am working with dirEntries. Great function by the way. I wanted to test for the number of files before I used a foreach on it. I looked here on stack overflow and the suggested method was to use the walkLength function (Count files in directory with Dlang). I took that suggestion. The return from it was a non-zero value - great. However, the foreach will not iterate over the result of dirEntries. It acts like the walkLength has left the dirEntries at the end of the range. Is there a way to reset it so I can start at the beginning of the dirEntries list? Here is some example code:
auto dFiles = dirEntries("",filter, SpanMode.shallow);
if (walkLength(dFiles) > 0)
{
writeln("Passed walkLength function");
foreach (src; dFiles)
{
writeln("Inside foreach");
}
}
The output shows it gets past the walkLength function, but never gets inside the foreach iterator.
Am I using dirEntries wrong? I have looked at Ali Cehreli's great book Programming in D as someone suggest. Nothing stuck out at me. I have looked online and nothing points to my interpretation of the problem. Of course, I could be completely off base on what the problem really is.
dirEntries gives you a range. You consume that range with walkLength and reach its end. Then you attempt to read more entries from it with the foreach loop. However, you have already reached its end, so there is nothing more to read.
You can either repeat the dirEntries call, use the array function from std.array to convert the range to an array, or use the .save function to create a copy of the range that you pass to walkLength.
If you don't care about the length and only care about whether it's empty, you can use the .empty property of the range instead of walkLength.

Getting `illegal pointer` error when using AddFriend from ROOT(cern)

Aim;
I wish to compare the contents of two ROOT TTree objects that have identical structure (but not identical contents obviously). The best way to do this seems to be using AddFriend.
Problem;
I am getting this error message;
Error: illegal pointer to class object t3 0x0 1681 makeFriends.C:6:
*** Interpreter error recovered ***
What I've tried so far;
After running the example at the bottom of this page successfully I decided to reduce it down to just the reading and friend adding section, as I had already created tree3.root and tree3f.root in the first run. So I had a file called tree3.C containing;
// Function to read the two files and add the friend
void tree3r() {
TFile *f = new TFile("tree3.root");
TTree *t3 = (TTree*)f->Get("t3");
// Add the second tree to the first tree as a friend
t3->AddFriend("t3f","tree3f.root");
// Draw pz which is in the first tree and use pt
// in the condition. pt is in the friend tree.
//t3->Draw("pz","pt>5");
}
This worked as expected, when loaded (root[] .L tree3.C) and run (root[] tree3r()) from the root prompt.
So I put a copy in a folder containing both of my root files, plainMaskOutput.root and DNMaskOutput.root, and changed strings in the copy to match the names of my files. So I have;
// Function to read the two files and add the friend
void tree3r() {
TFile *f = new TFile("plainMaskOutput.root");
TTree *t3 = (TTree*)f->Get("t3");
// Add the second tree to the first tree as a friend
t3->AddFriend("t3f","DNMaskOutput.root");
// Draw pz which is in the first tree and use pt
// in the condition. pt is in the friend tree.
//t3->Draw("pz","pt>5");
}
Which gives the error above. I dont understand why these things are behaving diffrently? Why can't they just be friends?
It turned out that TFiles method Get might return null, indicating the failure. You were not taking that into account. Why does it return null in your case?
According to the link I provided in the comments (https://root.cern.ch/phpBB3/viewtopic.php?t=12407) it is because your file doesn't contain a tree having a name you provided.
It will be better to add an explicit check of the returned value from Get. if the file gets changed later, your program will start to crash again.
The problem is that plainMaskOutput.root is a file name and the string inside the Get() parenthesis is the tree name. The file called plainMaskOutput.root did not contain a tree by the name t3 it contained one by the name HitsTree. So the line should have been;
TTree *foo = (TTree*)f->Get("HitsTree");
Similarly, the add friend command needed to have the name of the tree stored in DNMaskOutput.root, but as they have the same name it should be aliased;
foo->AddFriend("DNHitsTree = HitsTree","DNMaskOutput.root");
This is just the problem I was having this time, it may not always be the problem associated with this error. I am not knowledgeable enough in this area to say what other problems are possible.

MFC C++ Always returning EOF when I have access to file

I am currently stuck in this problem that I do not have any idea to fix. It is regarding a previous question that I have asked here before. But I will reiterate again as I found out the problem but have no idea to fix it.
My program accesses a text file that is updated constantly every millisecond 24/7. It grabs the data line by line and does comparison on each of the line. If any thing is "amiss"(defined by me), then I log that data into a .csv file. This program can be run at timed intervals(user defined).
My problem is that this program works perfectly fine on my computer but yet it doesnt on my clients computer. I have debug the program and these are my findings. Below is my code that I have reduced as much possible to ease the explanation process
int result;
char ReadLogLine[100000] = "";
FILE *readLOG_fp;
CString LogPathName;
LogPathName = Source_Folder + "\\serco.log"; //Source_Folder is found in a .ini file. Value is C:\\phython25\\xyratex\\serco_logs
readLOG_fp = fopen(LogPathName, "r+t");
while ((result = fscanf(readLOG_fp, "%[^\n]\n", ReadLogLine)) != EOF) // Loops through the file till it reaches the end of file
{
Sort_Array(); // Here is a function to sort the different lines that I grabbed from the text file
Comp_State(); // I compare the lines here and store them into an array to be printed out
}
fclose(readLOG_fp);
GenerateCSV(); // This is my function to generate the csv and print everything out
In Sort_Array(), I sort the lines that I grab from the text file as they could be of different nature. For example,
CStringArray LineType_A, LineType_B, LineTypeC, LineTypeD;
if (ReadLogLine == "Example line a")
{
LineType_A.add(ReadLogLine);
}
else if (ReadLogLine == "Example line b")
{
LineType_B.add(ReadLogLine);
}
and so on.
In CompState(), I compare the different values within each LineType array to see if there are any difference. If it is different, then I store them into a seperate array to print. A simple example would be.
CStringArray PrintCSV_Array;
for (int i = 0; i <= LineType_A.GetUpperBound(); i++)
{
if (LineType_A.GetAt(0) == LineType_A.GetAt(1))
{
LineType_A.RemoveAt(0);
}
else
{
LineType_A.RemoveAt(0);
PrintCSV_Array.Add(LineType_A.GetAt(0);
}
}
This way I dont have an infinite amount of data in the array.
Now to the GenerateCSV function, it is just a normal function where I create a .csv file and print whatever I have in the PrintCSV_Array.
Now to the problem. In my client's computer, it seems to not print anything out to the CSV. I debugged the program and found out that it keeps failing here.
while ((result = fscanf(readLOG_fp, "%[^\n]\n", ReadLogLine)) != EOF) // Loops through the file till it reaches the end of file
{
Sort_Array(); // Here is a function to sort the different lines that I grabbed from the text file
Comp_State(); // I compare the lines here and store them into an array to be printed out
}
fclose(readLOG_fp);
It goes into the while loop fine as I did some error checking there in the actual program. The moment it goes into the while loop it breaks out of it suggesting to me it reach EOF for some reason. When that happens, the program has no chance to go into both the Sort_Array and Comp_State functions thus giving me a blank PrintCSV_Array and nothing to print out.
Things that I have checked is that
I definitely have access to the text file.
My thoughts were because the text file is updated every
millisecond, it may have been opened by the other program to write
into it and thus not giving me access OR the text file is always in
an fopen state therefore not saving any data in for me to read. I
tested this out and the program has value added in as I see the KB's
adding up in front of my eyes.
I tried to copy the text file and paste it somewhere else for my
program to read, this way I definitely have full access to it and
once I am done with it, Ill delete it. This gave me nothing to print
aswell.
Am I right to deduce that it is always giving me EOF thus this is
having problems.
while ((result = fscanf(readLOG_fp, "%[^\n]\n", ReadLogLine)) != EOF) // Loops through the file till it reaches the end of file
If yes, How do I fix this?? What other ways can I make it read every line. I have seriously exhausted all my ideas on this problem and need some help in this.
Thanks everyone for your help.
Error is very obvious ... you might have over looked it..
You forgot to open the file.
FILE *readLOG_fp;
CString LogPathName;
LogPathName = Source_Folder + "\\serco.log";
readLOG_fp = fopen(LogPathName.GetBuffer());
if(readLOG_fp==NULL)
cout<<"Error: opening file\n";