I'm trying to write some code that will read numbers from one file and put those numbers into a list and then print the list in another file. I'm having trouble trying to get the numbers from the infile to read correctly. The program compiles ok but when the list is displayed it has the wrong numbers in it and I'm not sure where the numbers came from.

#include <iostream>
#include <fstream>
using namespace std;

// Singly-linked list node
class Link {
public:
  int element;		// Value for this node
  Link *next;		// Pointer to next node in list

  Link(const int elemval, Link* nextval =NULL)
    { element = elemval;  next = nextval; }

  Link(Link* nextval =NULL) { next = nextval; }
};

class MyList {
  private:

    Link* head;				// Pointer to list header
    Link* tail;				// Pointer to last int in list 
    Link* fence;			// Last element on left side
    int leftcnt;            // Size of left partition
    int rightcnt;			// Size of right partition

    // Initialization routine.
    // note that it's inline.
    void init() {
      fence = tail = head = new Link;
      leftcnt = rightcnt = 0;
    }

  public:

    MyList(int size = 1000) { init(); }
    bool insert(const int);
    bool append(const int);
    void print() const;        
    void next() {
      if (fence != tail) // Don't move fence if right empty
        { fence = fence->next; rightcnt--; leftcnt++; }
    }
    

};

int main() {

  MyList L1;
  char temp;
  ifstream inStream;
  ofstream outStream;
  
  inStream.open("test.txt");
  outStream.open("testout.txt");
  if (inStream.fail()){
     cout << "Input file opening failed.\n";
     }  
  if (inStream.fail()){
     cout << "Output file opening failed.\n";
     } 
  inStream.get(temp);
  while (!inStream.eof()) {
       L1.insert(temp);
       inStream >> temp;
     }

  L1.print();

  inStream.close( );
  outStream.close( );

  cout << endl;
  system("pause");
  return 0;
}

bool MyList::insert(const int item) {
  fence->next = new Link(item, fence->next);  
  if (tail == fence) tail = fence->next;  // New tail
  rightcnt++;
  return true;
}

bool MyList::append(const int item) {
  tail = tail->next = new Link(item, NULL);
  rightcnt++;
  return true;
}

void MyList::print() const {
  Link* temp = head;
  cout << temp->next->element << " ";

}

Right now I have it so it just print the code on the screen and it does not output to a file. Just trying to get the inStream working correctly. Any idea whats going on here??

Recommended Answers

All 6 Replies

Well, to begin with, you're reading a leading character from the file. If that leading character is actually part of one of the numbers you want to read, you've corrupted your input stream by changing the starting offsets of each read. Further, the variable you're using to read numbers is a char, so you're not really reading numbers. Instead of this:

inStream.get(temp);
while (!inStream.eof()) {
  L1.insert(temp);
  inStream >> temp;
}

Try this:

int temp;

while ( inStream>> temp )
  L1.insert ( temp );

Great that worked. But I've got some new problems. When the list is displayed on the screen the first number in the list is some long number that is not part of the file. So if text.txt contained...

5
6
7
8
9
10

Then the list would display.

< | 20011051000 5 6 7 8 9 >

How do I get the list to display the full list without that junk number?

#include <iostream>
#include <fstream>
using namespace std;

// Singly-linked list node
class Link {
public:
  int element;		// Value for this node
  Link *next;		// Pointer to next node in list

  Link(const int elemval, Link* nextval =NULL)
    { element = elemval;  next = nextval; }

  Link(Link* nextval =NULL) { next = nextval; }
};

class MyList {
  private:

    Link* head;				// Pointer to list header
    Link* tail;				// Pointer to last int in list 
    Link* fence;			// Last element on left side
    int leftcnt;            // Size of left partition
    int rightcnt;			// Size of right partition

    void init() {
      fence = tail = head = new Link;
      leftcnt = rightcnt = 0;
    }

  public:

    MyList(int size = 1000) { init(); }
    bool insert(const int);
    bool append(const int);
    void print() const;        
    void next() {
      if (fence != tail) // Don't move fence if right empty
        { fence = fence->next; rightcnt--; leftcnt++; }
    }
    

};


int main() {

  MyList L1;
  int temp;
  ifstream inStream;
  ofstream outStream;
  
  inStream.open("test.txt");
  outStream.open("testout.txt");
  if (inStream.fail()){
     cout << "Input file opening failed.\n";
     }  
  if (inStream.fail()){
     cout << "Output file opening failed.\n";
     } 
  while (!inStream.eof()) {
       L1.append(temp);
       inStream >> temp;
     }

  L1.print();

  inStream.close( );
  outStream.close( );

  cout << endl;
  system("pause");
  return 0;
}

bool MyList::insert(const int item) {
  fence->next = new Link(item, fence->next);  
  if (tail == fence) tail = fence->next;  // New tail
  rightcnt++;
  return true;
}

bool MyList::append(const int item) {
  tail = tail->next = new Link(item, NULL);
  rightcnt++;
  return true;
}

void MyList::print() const {
  Link* temp = head;
  cout << "< ";
  while (temp != fence) {
    cout << temp->next->element << " ";
    temp = temp->next;
  }
  cout << "| ";
  while (temp->next != NULL) {
    cout << temp->next->element << " ";
    temp = temp->next;
  }
  cout << ">\n";
}
while (!inStream.eof()) {
  L1.append(temp);
  inStream >> temp;
}

You append temp before ever reading anything. That's one of two good reasons not to use eof() as a loop condition. The other reason is that you can get an off-by-one error and process the last item in the file twice. This is shorter and works better:

while ( inStream>> temp )
  L1.append ( temp );
commented: Thanks for the help again!! +1

Ok I understand now, thanks for your help!! One last question.

How do I get the list to be sent to an output file? Should I put it in the MyList::print function or keep it in the Main function?

>>How do I get the list to be sent to an output file? Should I put it in the MyList::print function or keep it in the Main function?

My advice---Neither. Create a writeToFile() method for the MyList class.

My second choice, create a generic print function and pass it the stream you want to use, but then you have to worry about whether the stream needs to be associated with a file or not. You know it will need to be associated with a file if you use a dedicated function rather than a generic print() function.

My last choice would be to use a free standing function. Since you want to print a list and not some other object then keep functions associated with a given object type with that object type.

Nevermind, I was able to get the output to work. Thanks for all your help!!!!

Thanks for the post lerner, that is exactally what I did.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.