Click to See Complete Forum and Search --> : wrong order


Nasty2
April 6th, 2005, 05:43 AM
Im working on an application using a linked list.
The user enters a number and this is added as a new link in the linked list.
The user can then decide to display all the data in the links of the linked list.
If the user enters the following numbers in this order:

1
2
3
4

the application will display:

4
3
2
1

This is fine, i think, as a linked list works with Last In First Out. (am i right?)

I can also write the contents to a text file..... and they are written in the order that they are displayed in. That is:

4
3
2
1

Now here is my problem, the application can read each number from the text file and re-input them into the linked list, the problem is that they are being entered in the wrong sequence as the application starts from the BOF (ie. 4). After reading from the text file, if i display the contents of the linke dlist, they are shown as:

1
2
3
4

This is wrong!!!
Any ideas please?

marten_range
April 6th, 2005, 06:38 AM
Provide example code and information regarding what platform.

Ejaz
April 6th, 2005, 06:44 AM
This is fine, i think, as a linked list works with Last In First Out. (am i right?)

Not necessarily, stack is Last In First Out. You can use std::list (http://www.msoe.edu/eecs/ce/courseinfo/stl/list.htm), and use the reverse interators or can use the member function reverse which reverse the order of the elements.

Nasty2
April 6th, 2005, 06:49 AM
using Visual Studio .NET
console applcation.

Thanks Ejaz, but I cannot use the std::list. (not allowed to!!)

Here is the code for the function used to read from the file:

void linklist::readfile()
{
ifstream myFile("textfile.txt");

while(myFile)
{
int s;
myFile >> s;
this->additem(s); //adds each number it reads to the linked list
}

myFile.close();
cout << "All the data has been read from the file." << '\n';
cout << "Press Enter to continue!" << '\n';
getch();
}

Thanks

Ejaz
April 6th, 2005, 06:55 AM
Is this a class assignment? :) Anyway, you didn't mention that its single link list (I guess) or double link list. In case of double, you can traverse backwards, or you can provide the functionality like push_front, where you insert the elements at the front side always, or provide the facility to reverse the link list yourself.

BigEvil
April 6th, 2005, 07:38 AM
Add a recursive readnum() function
void linklist::readfile()
{
ifstream myFile("textfile.txt");
readnum();
myFile.close();
cout << "All the data has been read from the file." << '\n';
cout << "Press Enter to continue!" << '\n';
getch();
}
void linklist::readnum()
{
if(myFile)
{
int s;
myFile>>s;
readnum();
this->additem(s); // Number read first will be added last
}
}

Or instead of the recursive method, instead of adding the new node at the beginning of the list, add it at the end.
node *n = new node;
n->info = number read from file;
n->next = NULL;
node *end = first; // first (or list) = pointer to beginning of the list
if(end==NULL) // If list is empty
first = n, end = n;
else
{
while(end->next !=NULL) //Traverse to last node of list
end = end->next;
end->next = n; // Add new node after the last node
}

First one will be faster I guess, coz you won't have to traverse to the end of the list each time, but it will consume more memory (you can keep a pointer to end node in 2nd method, but it might make the code more complicated).

NoHero
April 6th, 2005, 08:05 AM
Add a recursive readnum() function
void linklist::readfile()
{
ifstream myFile("textfile.txt");
readnum();
myFile.close();
cout << "All the data has been read from the file." << '\n';
cout << "Press Enter to continue!" << '\n';
getch();
}
void linklist::readnum()
{
if(myFile)
{
int s;
myFile>>s;
readnum();
this->additem(s); // Number read first will be added last
}
}

Or instead of the recursive method, instead of adding the new node at the beginning of the list, add it at the end.
node *n = new node;
n->info = number read from file;
n->next = NULL;
node *end = first; // first (or list) = pointer to beginning of the list
if(end==NULL) // If list is empty
first = n, end = n;
else
{
while(end->next !=NULL) //Traverse to last node of list
end = end->next;
end->next = n; // Add new node after the last node
}

First one will be faster I guess, coz you won't have to traverse to the end of the list each time, but it will consume more memory (you can keep a pointer to end node in 2nd method, but it might make the code more complicated).

why reinventing the wheel? There is a std::vector, a std::list and a std::stack implementation...

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vcstdlib/html/vclrfStackstack.asp

Nasty2
April 6th, 2005, 08:26 AM
NoHero...... as i mentioned in my previous post, i cannot use any of those implementations....... got to create my own!

BigEvil....... first example you provided.....

void linklist::readfile()
{
ifstream myFile("textfile.txt");
readnum();
myFile.close();
cout << "All the data has been read from the file." << '\n';
cout << "Press Enter to continue!" << '\n';
getch();
}

void linklist::readnum()
{
if(myFile)
{
int s;
myFile>>s;
readnum();
this->additem(s); // Number read first will be added last
}
}

myFile is not identified as it is declared in the readfile function. I declared on top of the .cpp file and it worked fine (is there any other way i can declare this not globally????)

Otherwise, it worked fine: output was:
5
4
3
2
1
-858993460 <--------- what is this?

Thanks

BigEvil
April 6th, 2005, 08:26 AM
Thanks Ejaz, but I cannot use the std::list. (not allowed to!!)
he's not allowed to use std::list

NoHero
April 6th, 2005, 08:30 AM
If you rewrite the german comments you can use the stack I have written in school last year: stack_t.h (http://members.a1.net/nohero/stack_t.h) (Template), stack_c.h (http://members.a1.net/nohero/stack_c.h) (Class for ints), stack_f.h (http://members.a1.net/nohero/stack_f.h) (Functions for C).

NoHero
April 6th, 2005, 08:31 AM
-858993460 <--------- what is this?

An invalid value, it is -1... so it is invalid. You are running into deleted/freed memory boy :)

BigEvil
April 6th, 2005, 08:43 AM
myFile is not identified as it is declared in the readfile function. I declared on top of the .cpp file and it worked fine (is there any other way i can declare this not globally????)
Oops! You can pass it as an argument to readnum()

Try this... not very sure about it though!
if(myFile)
{
int s;
if(!myFile>>s) // If this doesn't display anything, remove the !
return;
readnum();
this->additem(s); // Number read first will be added last
}

An invalid value, it is -1... so it is invalid. You are running into deleted/freed memory boy
Or maybe myFile>>s failed :confused: Nasty2, show us your code for additem if the above changes don't work :D

Nasty2
April 6th, 2005, 08:54 AM
to pass myFile as an argument i've got to do the follwong changes right??:

void linklist::readfile()
{
ifstream myFile("textfile.txt");
readnum(myFile);

cout << "All the data has been read from the file." << '\n';
cout << "Press Enter to continue!" << '\n';
getch();
}

void linklist::readnum(ifstream filename)
{
if(myFile)
{
int s;
if(!myFile >> s)
return;
readnum();
this->additem(s); // Number read first will be added last
}
myFile.close();
}

its giving me an error in the .h file, where i got:
void readnum(ifstream filename);

BigEvil
April 6th, 2005, 08:59 AM
What's the error?

Its better to pass it by reference

void linklist::readnum(ifstream &filename)

btw, you're accepting it as "filename" and trying to read it from myFile...

so change the declaration to
void linklist::readnum(ifstream &myFile)

Nasty2
April 6th, 2005, 09:04 AM
it's telling me syntax error: identifier 'ifstream' and points to this part of the class:

public:
void readnum(ifstream &myFile); <--------------

Nasty2
April 6th, 2005, 09:53 AM
the additem code is as follows:

void linklist::additem(int d)
{
link* newlink = new link;
newlink->data = d;
newlink->next = first;
first = newlink;
}

HighCommander4
April 6th, 2005, 05:31 PM
it's telling me syntax error: identifier 'ifstream' and points to this part of the class:

public:
void readnum(ifstream &myFile); <--------------

I assume you didn't put "using namespace std;" in your header file (and you shouldn't!), so you should change ifstream to std::ifstream (all the stream classes are in the std namespace).