Linked List

Nov 23, 2021 at 6:22am
100 Mary
110 John
111 David
112 Sofia
121 Maria
144 Mia

Lets say given above is the user.txt file and i want make a function to read all these data using a linked list with struct .

Any idea how to create this??
Nov 23, 2021 at 6:36am
https://www.cplusplus.com/forum/beginner/280683/
Well you already know about reading files and structures.
Enough to at least make a start on the problem.

Can you use https://en.cppreference.com/w/cpp/container/list or is the exercise to roll your own list?
Nov 23, 2021 at 6:42am
well yeah i know that but my concern is to roll my own list using linked list
Nov 23, 2021 at 7:32am
https://en.wikipedia.org/wiki/Linked_list

You could make a start by just using std::list while you get the rest of the code working.

So when you replace std::list with mylist, you'll know where the problem is going to be when it doesn't work, and you'll know that you've done it right when it does work.
Nov 23, 2021 at 9:05am
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include <iostream>
#include <fstream>
using namespace std;

struct node
{
   string id, name;
   node *next;
};

void print( node *n )
{
   for ( ; n; n = n->next ) cout << n->id << ' ' << n->name << '\n';
}

int main()
{
   ifstream in( "user.txt" );
   node *root = nullptr, *tail = nullptr;
   for ( string id, name; in >> id && getline( in, name ); tail = ( root ? tail->next : root ) = new node{ id, name, nullptr } );
   print( root );
}


100  Mary
110  John
111  David
112  Sofia
121  Maria
144  Mia



Nov 24, 2021 at 5:40am
when i run the this program it has an error on nullptr how do i correct this?
Nov 24, 2021 at 6:05am
Nov 24, 2021 at 9:37am
jabeh wrote:
when i run the this program it has an error on nullptr how do i correct this?


Well, you could use NULL instead of nullptr.

However, if your compiler won't cope with at least C++11 (as @salem c noted) then you are missing out on a lot.
Nov 24, 2021 at 10:31am
This version doesn't use explicit nullptr:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#include <iostream>
#include <fstream>
#include <string>
#include <iomanip>
using namespace std;

struct node {
	string id, name;
	node *next {};
};

void print(const node* n) {
	for (; n; n = n->next)
		cout << n->id << ' ' << n->name << '\n';
}

int main() {
	ifstream in("user.txt");

	if (!in)
		return (cout << "Cannot open file\n"), 1;

	node *root {}, *tail {};

	for (string id, name; in >> id && getline(in >> ws, name); tail = (root ? tail->next : root) = new node {.id = id, .name = name});

	print(root);
}

Nov 24, 2021 at 12:46pm
 
tail = ( root ? tail->next : root ) = new node{ id, name, nullptr }


I decided so that I can get myself up to par I'm going to spend the next week or so reading beginners questions.

I found the above code really clever, and think I understand it.

Let me see if I can put it in words: if root is false then root equals a new node, else the take the tail's next and make it a new node, regardless the tail becomes next.

Please let me know if you find this sentence correct?
Last edited on Nov 24, 2021 at 12:48pm
Nov 24, 2021 at 12:52pm
It's to do really with placement of the first node, depending on whether we have an empty list or not.

The right-hand assignment is done first.

If root is non-null then there is an existing list and the (current) tail->next pointer is set to point to a new node. In the one-off case that root is null then the list is currently empty and we have to set root to the new node.

After all these shenanigans the left-hand assignment is done and the tail pointer is set to point to the newly-assigned node.


It has probably been abbreviated beyond utility, I admit. I usually do linked-list assignment with several more easy-to-read if blocks. The assembled code probably looks the same.


To be fair, I think I pinched the idea from @dutch at some point - just can't remember where. It was one of his single-line statements that left me in awe.




If you don't mind the reversed order in a forward list then you can construct more easily by adding at the start instead and ditch the tail pointer.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include <iostream>
#include <fstream>
using namespace std;

struct node
{
   string id, name;
   node *next;
};

void print( node *n )
{
   for ( ; n; n = n->next ) cout << n->id << ' ' << n->name << '\n';
}

int main()
{
   ifstream in( "user.txt" );
   node *root = nullptr;
   for ( string id, name; in >> id && getline( in, name ); root = new node{ id, name, root } );
   print( root );
}

Entries come out in reverse order:
144  Mia
121  Maria
112  Sofia
111  David
110  John
100  Mary

though you can fix that by changing the print() function:
1
2
3
4
5
6
7
8
void print( node *n )
{
   if ( n )
   {
      print( n->next );
      cout << n->id << ' ' << n->name << '\n';
   }
}

to give
100  Mary
110  John
111  David
112  Sofia
121  Maria
144  Mia



Last edited on Nov 25, 2021 at 9:17am
Topic archived. No new replies allowed.