Solved

Link List linking problem

Posted on 2003-11-28
30
848 Views
Last Modified: 2013-12-14
I am running the following function but have two problems:
1)  there is an empty node constructed before this call, this node does not move away from the Head
2)  it does not seem to load the first node from the text file

Once this function runs, I have an add node (one) function that adds nodes that pushback the empty node away from the head.

bool llistBooks::loadFromFile(string fileName)
{      ifstream in;                              in.open(fileName.c_str());                        if(!in)                                    cout << "There was a problem loading files";
else
{              string Iprice, Icost;                              double the_double;                              bookNodePtr here;                              here = new bookNode;                        while(!in.eof())
      {      getline(in,here->title,'\n');
            getline(in,here->author, '\n');
            getline(in,here->publisher,'\n');
            getline(in,here->isbn, '\n');
            getline(in,Iprice, '\n');
            the_double = strtod(Iprice.c_str(), NULL);                  here->price = the_double;                        getline(in,Icost, '\n');                              the_double = strtod(Icost.c_str(), NULL);                  here->cost = the_double;
            this->newNode(here);
      }                                          here = NULL;                              delete here;      }
            in.close();                                    return true;      }
0
Comment
Question by:puckerhoop
  • 16
  • 11
  • 2
  • +1
30 Comments
 
LVL 4

Expert Comment

by:n_fortynine
ID: 9840614
A few things:

What does this->newNode(here); do?
Normally I would assume this call creates a new bookNode next to the bookNode here is pointing to, but I want to see what it's doing.

You never assigned here to the head of the list anyway. Or have you?

0
 
LVL 3

Expert Comment

by:monkesdb
ID: 9840626
let's take a better look at the code. if you could post it like this in the first place it's would be more helpful.


bool llistBooks::loadFromFile(string fileName)
{
     ifstream in;
     in.open(fileName.c_str());

     if(!in)
     {
          cout << "There was a problem loading files";
          return false;  //this could be useful.
     }
     else
     {
          string Iprice, Icost;
          double the_double;
          bookNodePtr here = new bookNode();   //you missed the parenthases

          while(!in.eof())
          {
              getline(in,here->title,'\n');
              getline(in,here->author, '\n');
              getline(in,here->publisher,'\n');
              getline(in,here->isbn, '\n');
              getline(in,Iprice, '\n');
              the_double = strtod(Iprice.c_str(), NULL);
              here->price = the_double;
              getline(in,Icost, '\n');
              the_double = strtod(Icost.c_str(), NULL);
              here->cost = the_double;
              this->newNode(here);
          }
          here = NULL;
          delete here;
     }
     in.close();
     return true;
}


ok, looking at this code you have no error. the error may be in llistBooks::newNode(bookNodePtr)
or it might be where ever you initiate the linked list.
0
 

Author Comment

by:puckerhoop
ID: 9841216
The head of the list was assigned prior to calling this function.
It was assigned with a default constructor.  This is the empty node that I mentioned.

The newNode function is:
void llistBooks::newNode(bookNodePtr& here)
{
here = new bookNode;                        
here->next = head;            
head = here;                              
}
0
 
LVL 4

Expert Comment

by:dhyanesh
ID: 9841379
Hi

Your newNode function is incorrect. The newNode function creates a new here overwriting the old one. Hence the new 'here' will be empty as you are getting it to be.

It should be something like:

void llistBooks::newNode(bookNodePtr& here)
{
bookNodePtr temp = new bookNode();                    
//copy all values to new node created
temp->title = here->title;
temp->author = here->author;
temp->publisher=here->publisher;
temp->isbn=here->isbn;
temp->price=here->price;
temp->cost=here->cost;
temp->next = head;
head = temp;
}

Dhyanesh
0
 
LVL 4

Expert Comment

by:dhyanesh
ID: 9841388
Hi

Another alternative is not to create the new node in function newNode but use the created node 'here' in loadFromFile as part of your link list.

i.e. your newNode function would then be:

void llistBooks::newNode(bookNodePtr& here)
{
here->next = head;          
head = here;                        
}

However then in you loadFromFile function you will not have to delete the node 'here'

i.e. your function will be:

bool llistBooks::loadFromFile(string fileName)
{
    ifstream in;
    in.open(fileName.c_str());

    if(!in)
    {
         cout << "There was a problem loading files";
         return false;  //this could be useful.
    }
    else
    {
         string Iprice, Icost;
         double the_double;
         bookNodePtr here = new bookNode();   //you missed the parenthases

         while(!in.eof())
         {
             getline(in,here->title,'\n');
             getline(in,here->author, '\n');
             getline(in,here->publisher,'\n');
             getline(in,here->isbn, '\n');
             getline(in,Iprice, '\n');
             the_double = strtod(Iprice.c_str(), NULL);
             here->price = the_double;
             getline(in,Icost, '\n');
             the_double = strtod(Icost.c_str(), NULL);
             here->cost = the_double;
             this->newNode(here);
         }                                                                    
     //here = NULL;
    //delete here;
    }
    in.close();
    return true;
}



Dhyanesh
0
 

Author Comment

by:puckerhoop
ID: 9842191
Dhyanesh: when i do as suggested, it continually loads the last item from file... it is not finding "eof" anymore!
0
 
LVL 4

Expert Comment

by:n_fortynine
ID: 9843295
puckerhoop,

Do you *have to* use the newNode function? If not, do you have an insert function? I think I suggested this some time ago, but I'm gonna say this again:

Assume you have an insert function that takes in an instance of the bookNode and insert its information into the list.
something like
void llistBooks::insert(const &bookNode newItem) {
//...
}
then you can do

bool llistBooks::loadFromFile(string fileName)
{
    ifstream in;
    in.open(fileName.c_str());

    if(!in)
    {
         cout << "There was a problem loading files";
         return false;
    }
    else
    {
         string Iprice, Icost;
         bookNodePtr here = new bookNode;

         while(!in.eof())
         {
             getline(in,here->title,'\n');
             getline(in,here->author, '\n');
             getline(in,here->publisher,'\n');
             getline(in,here->isbn, '\n');
             getline(in,Iprice, '\n');          
             here->price = strtod(Iprice.c_str(), NULL);
             getline(in,Icost, '\n');
             here->cost = strtod(Icost.c_str(), NULL);
             insert(&here);
         }
                                             
         here = NULL;
    }
    in.close();
    return true;
}
0
 

Author Comment

by:puckerhoop
ID: 9843507
I have such a function, but that function is not constructed to handle this situation.  It is structured to handle the same type of inputs from display.  
That is why I created the newNode function.
The other option would be to create the Node within this function, but I have not been able to get that to work correctly.
0
 
LVL 4

Expert Comment

by:n_fortynine
ID: 9843542
then you can try:
   //assume list is empty.
   else
    {
         string Iprice, Icost;
         head = new bookNode;    //get in the first item so that you can assign to head
         getline(in,head->title,'\n');
         getline(in,head->author, '\n');
         getline(in,head->publisher,'\n');
         getline(in,head->isbn, '\n');
         getline(in,Iprice, '\n');          
         head->price = strtod(Iprice.c_str(), NULL);
         getline(in,Icost, '\n');
         head->cost = strtod(Icost.c_str(), NULL);        

         bookNodePtr here = head->next;

         while(!in.eof())
         {
             here = new bookNode;
             getline(in,here->title,'\n');
             getline(in,here->author, '\n');
             getline(in,here->publisher,'\n');
             getline(in,here->isbn, '\n');
             getline(in,Iprice, '\n');          
             here->price = strtod(Iprice.c_str(), NULL);
             getline(in,Icost, '\n');
             here->cost = strtod(Icost.c_str(), NULL);
             here = here->next;
         }
                                             
         here = NULL;
    }

Let me know if that'll work.
0
 

Author Comment

by:puckerhoop
ID: 9843544
from the way i have structured this function, with the getline feeding in the data... the variables that my insert function requires are considered undeclared within the above function.
I am trying to do this without redoing this entire function.
0
 
LVL 4

Expert Comment

by:n_fortynine
ID: 9843581
You probably have understood that load data from file to an empty list is not different than continuously inserting into that list, thus making your loadfromFile function inevitably similar to an insert function (that is, if you do not want to use or do not have an insert function that does that inserting job).

I'm not quite sure what you mean by
>>the variables that my insert function requires are considered undeclared within the above function.

0
 

Author Comment

by:puckerhoop
ID: 9843648
Prior to this function an empty list is created.
When I do as suggested, nothing is loading.
0
 
LVL 4

Expert Comment

by:n_fortynine
ID: 9843690
If you don't mind, I would like to see the entire files (header, implementation, driver, and data file). It would be easier to pinpoint the problem if I could look at the code as a whole. Trying to trouble-shoot like this is kinda hard to do.
0
 

Author Comment

by:puckerhoop
ID: 9843720
DRIVER:
#include <string>
#include <iostream>
#include <fstream>
using namespace std;
#include "llistBook.h"            //llistBook class definition

void main ()
{
string temp;
string temp2;                        
string book1 = "book1.txt";            //input filename
string book2 = "book2.txt";            //output filename
string book3 = "book3.txt";            //output filename
string      t_title, t_author, t_isbn, t_publisher;      
double t_price, t_cost;                                                
llistBooks test;            //declaration of an empty list of books

test.loadFromFile(book1);            //load data from file

t_title = "Great Expectations";      //start addition of new book
t_author = "Charles Dickens";
t_isbn = "0-393-96069-2";
t_publisher = "Norton";
t_price = 21.95;
t_cost = 15.01;
test.insertB(t_title, t_author, t_isbn, t_publisher, t_price, t_cost);            //insert new book

test.printAll();                  //print all to screen

temp = "0-13-095990-1";
test.deleteB(temp);                  //delete 5th book
      
test.printAll();                  //print all to screen
}
0
 
LVL 4

Expert Comment

by:n_fortynine
ID: 9843728
could you please post the other files (header, implementation) class llistBook as well?
0
How to improve team productivity

Quip adds documents, spreadsheets, and tasklists to your Slack experience
- Elevate ideas to Quip docs
- Share Quip docs in Slack
- Get notified of changes to your docs
- Available on iOS/Android/Desktop/Web
- Online/Offline

 

Author Comment

by:puckerhoop
ID: 9843729
HEADER:
#include <string>
#include <iostream>
using namespace std;

#ifndef LLISTBOOKS_H
#define LLISTBOOKS_H

struct bookNode {
string title;                  //title of book
string author;                  //author of book
string publisher;            //publisher of book
string isbn;                  //isbn of book
double price;                  //price of book
double cost;                  //cost of book
bookNode  *next;            //link to next node
};

typedef  bookNode* bookNodePtr;            //typedef declared for bookNode

class llistBooks {
public:
llistBooks();                  //constructor
~llistBooks();                  //destructor
bool insertB(string title, string author, string isbn, string publisher, double price, double cost);
bool deleteB(string &isbn);
bool findB(string &isbn) const;
bool printB(string isbn) const;
bool printAll() const;
bool saveToFile (string fileName) const;
bool loadFromFile(string fileName);
bool empty() const;
void llistBooks::newNode(bookNodePtr& here);

private:
bookNodePtr      head;                  };
{;
#endif
0
 
LVL 4

Expert Comment

by:n_fortynine
ID: 9843748
Sorry, not trying to be a pain here =) but how about the code for insertB and printAll?
0
 

Author Comment

by:puckerhoop
ID: 9843777
FUNCTIONS:
#include <stdlib.h>
#include <string>
#include <iostream>
#include <fstream>
using namespace std;
#include "llistBook.h"


llistBooks::llistBooks()            //constructor
{
head = NULL;                        
}
      
llistBooks::~llistBooks()      //destructor
{
if (empty() )                              
cout << "List is already empty." << endl;
  else
  {
   string next;                              
     while (! empty())                                 
     {
     next = deleteB(next);            //delete bookNodes
     }            
   }                              
cout << "You have destroyed all of the books!" << endl;
}


bool llistBooks::insertB(string title, string author, string isbn, string publisher, double price, double cost)
{
   bookNodePtr temp;                              
   temp = head;                        
   temp = new bookNode;                        
   temp->title = title;
   temp->author = author;
   temp->isbn = isbn;
   temp->publisher = publisher;
   temp->price = price;
   temp->cost = cost;
   temp->next = head;                          
   head = temp;                                          
cout << "\n#-#-#-#-#-#-#-#-#-#-#-#-#" << endl;
cout << "BOOK ADDED: " << temp->isbn << endl;
cout << "#-#-#-#-#-#-#-#-#-#-#-#-#" << endl;
return true;
}


bool llistBooks::deleteB(string &target)            //delete
{
   bookNodePtr before = head;                        
   bookNodePtr temp = before->next;                  
   for (before; before != NULL; before = before->next)      //for loop
   for (temp; temp != NULL; temp = temp->next)
   {
      if (temp->isbn == target)                          
      {                                          cout << "\n#############" << endl;            
cout << temp->isbn << "temp" << endl;
cout << before->isbn << "before" << endl;
     temp = before;
     before = temp->next;
     before->next = temp->next;
     cout << "BOOK DELETED" << endl;
     cout << "#############" << endl;
     delete temp;                        
     return true;                        
     }                                    
     else      
      before = before->next;                  
     }                              
   delete temp;                          
   return false;
}

bool llistBooks::loadFromFile(string fileName)
{
ifstream in;                              
in.open(fileName.c_str());                        
if(!in)                                    
   {
   cout << "There was a problem loading files";
   return false;
   }
else
   {
   string Iprice, Icost;                        
   double the_double;                        
   bookNodePtr head;
   head = new bookNode;      
while(!in.eof())
   {                                          getline(in,head->title,'\n');
getline(in,head->author, '\n');
getline(in,head->publisher,'\n');
getline(in,head->isbn, '\n');
getline(in,Iprice, '\n');
the_double = strtod(Iprice.c_str(), NULL);
head->price = the_double;                  
getline(in,Icost, '\n');                        
the_double = strtod(Icost.c_str(), NULL);            
head->cost = the_double;
   }                              
bookNodePtr here = head->next;
while(!in.eof())
{                        
here = new bookNode;
     getline(in,here->title,'\n');
     getline(in,here->author, '\n');
     getline(in,here->publisher,'\n');
     getline(in,here->isbn, '\n');
     getline(in,Iprice, '\n');
     the_double = strtod(Iprice.c_str(), NULL);         
     here->price = the_double;                   
     getline(in,Icost, '\n');                        
     the_double = strtod(Icost.c_str(), NULL);              
     here->cost = the_double;
     here = here->next;                        
    }                              
      here = NULL;                        
      delete here;                        
      }
      in.close();                                    return true;
      }


bool llistBooks::empty() const
{
   return (head == NULL);
}

      
void llistBooks::newNode(bookNodePtr& here)
{                              
   here->next = head;                              
   head = here;                              
}
0
 

Author Comment

by:puckerhoop
ID: 9843787
PRINTALL:
bool llistBooks::printAll() const
{
if (head == NULL)                              
{
cout<<"\nEmpty list.\n";
return false;
}
else
   {
   cout << "\nPRINT OUT OF ALL BOOKS:" << endl;
   cout << "~~~~~~~~~~~~~~~~~~~~~~~~~~" << endl;
   bookNodePtr here = head;                          
   while(here != NULL)                        
{                              
cout << "\n" << here->title;
cout << "\n" << here->author;
cout << "\n" << here->publisher;
cout << "\n" << here->isbn;
cout << "\n" << here->price;
cout << "\n" << here->cost;
cout << endl;
here = here->next;                              
}                                    
delete here;                              
return true;
 }
}
0
 
LVL 4

Expert Comment

by:n_fortynine
ID: 9843816
I see, so you are inserting books at the beginning of the list. Those functions look correct. The problem with loadfromFile is:

bool llistBooks::loadFromFile(string fileName) {
    ifstream in;
    in.open(fileName.c_str());
    if(!in) {
       cout << "There was a problem loading files";
       return false;
    }
    else
    {
       string Iprice, Icost;                    
       double the_double;                    
       //Commented out. bookNodePtr head;
       head = new bookNode;  //Using YOUR head pointer.
       //Commented out: while(!in.eof()) {
       getline(in,head->title,'\n');
       getline(in,head->author, '\n');
       getline(in,head->publisher,'\n');
       getline(in,head->isbn, '\n');
       getline(in,Iprice, '\n');
       the_double = strtod(Iprice.c_str(), NULL);
       head->price = the_double;              
       getline(in,Icost, '\n');                    
       the_double = strtod(Icost.c_str(), NULL);
       head->cost = the_double;
                           
       bookNodePtr here = head->next;
       while(!in.eof()) {                    
           here = new bookNode;
           getline(in,here->title,'\n');
           getline(in,here->author, '\n');
           getline(in,here->publisher,'\n');
           getline(in,here->isbn, '\n');
           getline(in,Iprice, '\n');
           the_double = strtod(Iprice.c_str(), NULL);        
           here->price = the_double;                
           getline(in,Icost, '\n');                    
           the_double = strtod(Icost.c_str(), NULL);            
           here->cost = the_double;
           here = here->next;
      }                        
     here = NULL;                    
     //No need to call delete here: delete here;
     }
     in.close();
     return true;
}

See if that would work now.
0
 

Author Comment

by:puckerhoop
ID: 9843865
not quite... i have to go out for a few hours & will play with it some more, when i return.
0
 
LVL 4

Expert Comment

by:n_fortynine
ID: 9843875
I have to go find something to eat as well so that works for both of us =)
0
 

Author Comment

by:puckerhoop
ID: 9844257
When I step thru, the line that is causing the problem is at the beginning of the function.  Your suggested code, that should work, as I have already set up bookNode?!
      head = new bookNode;
0
 

Author Comment

by:puckerhoop
ID: 9844273
actually it kicks it to disassembly but seems to load head (although it never prints).  
there is definetely a problem at the end of the function:
            here = here->next;      
it is not incrementing a new node, but overriding the same one over and over again.  I am going to work on this section
0
 
LVL 4

Expert Comment

by:n_fortynine
ID: 9844290
oops there might be an error there. It's been a long time:

bool llistBooks::loadFromFile(string fileName) {
    ifstream in;
    in.open(fileName.c_str());
    if(!in) {
       cout << "There was a problem loading files";
       return false;
    }
    else
    {
       string Iprice, Icost;                    
       double the_double;
             
       head = new bookNode;
       getline(in,head->title,'\n');
       getline(in,head->author, '\n');
       getline(in,head->publisher,'\n');
       getline(in,head->isbn, '\n');
       getline(in,Iprice, '\n');
       the_double = strtod(Iprice.c_str(), NULL);
       head->price = the_double;              
       getline(in,Icost, '\n');                    
       the_double = strtod(Icost.c_str(), NULL);
       head->cost = the_double;
                           
       bookNodePtr here = head;

       while(!in.eof()) {                    
           here->next = new bookNode;
           getline(in,here->title,'\n');
           getline(in,here->author, '\n');
           getline(in,here->publisher,'\n');
           getline(in,here->isbn, '\n');
           getline(in,Iprice, '\n');
           the_double = strtod(Iprice.c_str(), NULL);        
           here->price = the_double;                
           getline(in,Icost, '\n');                    
           the_double = strtod(Icost.c_str(), NULL);            
           here->cost = the_double;
           here = here->next;
      }
     here->next = NULL;                    
     }
     in.close();
     return true;
}
0
 

Author Comment

by:puckerhoop
ID: 9844387
that is better, but it only takes me back to where I started... the first data being pulled in from the file is being overriden by the 2nd set of data.  It looks good when I step thru it!
0
 

Author Comment

by:puckerhoop
ID: 9844390
actually, it is better than my original.. it is moving the original empty node to the end of the list, where it should be!
0
 

Author Comment

by:puckerhoop
ID: 9844393
and it is pushing the file in the opposite direction!
it is now loading the file into the list, backwards...
ie.  the node loaded last is the one that is next to the original empty node at the end of the list.
this doesn't matter for my program, i just found it interesting.
i am going to try and see how this plays into the problem with the missing 1st set of data from the file.
0
 
LVL 4

Accepted Solution

by:
n_fortynine earned 400 total points
ID: 9844539
Sorry I just felt asleep (just found out I had to work an 8h shift from 12pm-8pm tomorrow)...

Yeah, it's supposed to load data in that fashion:

Last data -> Next to last data -> .... -> 2nd data -> 1st data.

If you want it to load to be

1st data -> 2nd data -> ... -> Last data

All you have to do is to structure it like your insert function:

bool llistBooks::loadFromFile(string fileName) {
    ifstream in;
    in.open(fileName.c_str());
    if(!in) {
       cout << "There was a problem loading files";
       return false;
    }
    else
    {
       string Iprice, Icost;                    
       double the_double;
             
       head = new bookNode;
       getline(in,head->title,'\n');
       getline(in,head->author, '\n');
       getline(in,head->publisher,'\n');
       getline(in,head->isbn, '\n');
       getline(in,Iprice, '\n');
       the_double = strtod(Iprice.c_str(), NULL);
       head->price = the_double;              
       getline(in,Icost, '\n');                    
       the_double = strtod(Icost.c_str(), NULL);
       head->cost = the_double;
                           
       //The part before this stayed the same.
       head->next = NULL;
       
       bookNodePtr here;

       while(!in.eof()) {
           here = new bookNode;
           getline(in,here->title,'\n');
           getline(in,here->author, '\n');
           getline(in,here->publisher,'\n');
           getline(in,here->isbn, '\n');
           getline(in,Iprice, '\n');
           the_double = strtod(Iprice.c_str(), NULL);        
           here->price = the_double;                
           getline(in,Icost, '\n');                    
           the_double = strtod(Icost.c_str(), NULL);            
           here->cost = the_double;

           here->next = head;
           head = here;
        }

        here = NULL;
     }
     in.close();
     return true;
}

Let me know how things work out. =)
0
 

Author Comment

by:puckerhoop
ID: 9847134
I have played with the code and get one of three results:
1- none add
2- when I get the first node to attach... I lose the rest.
3- I get all but the first to attach
I am going to leave it at this point.
Thank you.
0

Featured Post

Why You Should Analyze Threat Actor TTPs

After years of analyzing threat actor behavior, it’s become clear that at any given time there are specific tactics, techniques, and procedures (TTPs) that are particularly prevalent. By analyzing and understanding these TTPs, you can dramatically enhance your security program.

Join & Write a Comment

When writing generic code, using template meta-programming techniques, it is sometimes useful to know if a type is convertible to another type. A good example of when this might be is if you are writing diagnostic instrumentation for code to generat…
Article by: SunnyDark
This article's goal is to present you with an easy to use XML wrapper for C++ and also present some interesting techniques that you might use with MS C++. The reason I built this class is to ease the pain of using XML files with C++, since there is…
The viewer will learn how to use NetBeans IDE 8.0 for Windows to connect to a MySQL database. Open Services Panel: Create a new connection using New Connection Wizard: Create a test database called eetutorial: Create a new test tabel called ee…
The goal of the video will be to teach the user the concept of local variables and scope. An example of a locally defined variable will be given as well as an explanation of what scope is in C++. The local variable and concept of scope will be relat…

708 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

15 Experts available now in Live!

Get 1:1 Help Now