Accessing struct member within node of linked list concept

I have created a linked list with a struct Student within a single node of said linked list. Within the Student struct, there are several struct members, namely student id, name, course etc.

There are multiple nodes in this linked list, each representing one student, and each contains all the student's information.

Say I intend to traverse the list to find a matching student id with the user's input to print out the student's info or to add student information into the node, how do I access the student id data within the node?

I have scoured the web for linked list samples similar to what I'm trying to do but seems like every tutorial / questions asked has only one data in one node. :/

For what I have tried so far, I tried declaring a char pointer to point to student id which is of char type, but then I can't point to the nodes with this pointer because this action requires Node pointer according to visual studio.
But using Node pointer, how do I point to the char variable(student id) within the node? I'm afraid I can't wrap my head around it.

Can someone please explain this concept to me as I JUST learned linked list and my understanding of it is still kinda vague

Thanks in advance for anyone willing to help.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
you dereference the pointer to get to the fields.   -> or * or [0] notation all work. 
something like 
student * head; //the list
/// populate list and such

...
student * tmp{head};
while(tmp && other conditions)
{
     if(*tmp.data == userinput)
       {cout << "you found a match\n"; break;}
   tmp = tmp->next;  
}
//if you get here and tmp is nullptr you did not find one.
Last edited on

Hi, thanks for replying, but I have a few more questions.

If I had already written:
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
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
using type = Student;

struct Node{
	type item;
	Node *next;
	Node(type);
};

struct List
{
	Node *head;
// and some other functions for List
};

struct Student {		

	char name[30];	
   	char id[12];
	char course[3];
//and some other functions for Student
};


bool search(Node *, Student *, char , int& );

int main()
{
//assign data to stu
list.insert(stu); //this function is not important, i wont insert the definition here
cin >> inputid;
search(head, idPTR, inputid,position);
}

bool search(Node *head, Student *idPTR, char inputid, int& position)
{
	Node *current = head;
	while (current != NULL)
	{
		if (strcmp(idPTR->id, inputid)==1)
			return true;
                idPTR= idPTR->next; 



	}

}

, in this case, if I call a Student *idPTR, will it be able to do the following: point to node, be dereferenced, access the field (id) ?



 
student * tmp{head};

This is a student pointer named tmp right, but why did u include {head} at the back?
And do I need to include anything else in the brackets in my situation?


And in your if(*tmp.data == userinput), do u not need to point to the head first, or have you already did that in your previous line(that i dont understand)?
Last edited on
, in this case, if I call a Student *idPTR, will it be able to do the following: point to node, be dereferenced, access the field (id) ?


that is a pointer. It needs memory before you can de-reference it. It can be forced to point to a node, but its not a node pointer and that indicates either some OOP magic or mad hacks. Mad hacks here are bad (there are a couple of places it can work, but lets not do this today), and I don't see any OOP magic, so no, it can't do that!

once it has memory, eg
idPTR = new Student;
then you can use id:
sprintf(*idPTR.id, "1234");

student * tmp{head};
this is modern c++ for
student *tmp = head;
it is just an initialization. Its in favor because it checks the type more forcefully than = does. This is also not important today.

And one more of those: this is cute, and there is a way to do this as well, where the type is 'soft' and can be defined by the user of the class. standard vector does this, eg vector<int> x; //x is a vector of ints here -- this is called a template. You will get to it.
using type = Student;

struct Node{
type item;

to do it your way, anything your student has that is needed by the list class (I dunno, say the list is sorted/ordered by "id") you would make a common interface for, eg getlistkey() function, and if all your types had this function, the list could get it regardless of the other details.
Last edited on
that is a pointer. It needs memory before you can de-reference it. It can be forced to point to a node, but its not a node pointer


ok this confirmed my suspicion thanks :)

to do it your way, anything your student has that is needed by the list class (I dunno, say the list is sorted/ordered by "id") you would make a common interface for, eg getlistkey() function, and if all your types had this function, the list could get it regardless of the other details.


im sorry but I totally do not understand what you are trying to say, im not sure its because of my limited knowledge on C++ or what.. anyway, what does all my "types" mean? do u mean all my structs...?

idPTR = new Student;
then you can use id:
sprintf(*idPTR.id, "1234");

now i understand the "assigning" memory to the pointer concept, but im pointing to existing nodes here, so I think this won't work? right?

in my insert function, I have a Node pointer named head which is pointing to the first node, so what I'm trying to do is basically: 1. access head 2. access the first node 3. access the "id" field
no matter im using pointer or anything, i just want to get to one of the fields within the node..TT
Last edited on
Types means this: using type = Student; //student is a specific type. you seem to only have the one right now.

if your list class were (for an example only) trying to sort the items based off student IDs, it needs access to student-IDs. you have tried to make the linked list generic (with the using statement at the top and node design), but it may be at some point you COULD need to know something about your data, and if that happens, you need a way to access that data. To keep it generic, if that happens, you should make a common interface (a function with the same name and parameters and return type) to get the data you needed, so it remains somewhat generic (the types being put into the list all need to support the interface). Its more of a C-style approach, because you don't know the c++ to do this yet. If its not part of the assignment, I would skip trying to make it generic right now instead and circle back to it once you know more about the tools. NONE of this matters to your code right now, but if you add another 'type' like student, it could.

-----------
pointing to existing nodes is fine, that means you have valid memory. at that point you CAN dereference it. My little snippit was just to show that after a new (or any other way to make the pointer valid) you can then dereference it.

----------
head is a pointer, and assuming it has memory,
head->item.id access it.
^^^^ THIS is exactly what I am talking about. ITEM is CURRENTLY a STUDENT and so it DOES HAVE an ID. If you change the first line of your code to this:
using type = double;
then this statement:
head->item.id
will not work anymore!! doubles don't have a .id field!
that is what all the blah blah in my first paragraph of this post is going on about. You would have to put double into a struct and add an id field for that 'common interface' (I said function earlier, but using the same name for a field would work too).

Again, this is way afield of what you need today. What all that boils down to is that either the using statement is not helpful, and you should just make node have a student type for 'item' for now, OR, you need to do some things to ensure your 'generic' list is usable on other types later, and these things you need to do... I tried to explain, but its complicated and again, its using C like ideas because you don't know c++ templates yet...
Last edited on
ok I think I get what you're trying to say now!!

Thanks so much for helping me out!
Ok. You already got that:
1
2
3
4
5
6
7
using type = Student;

struct Node {
	type item;
	Node *next;
	Node(type);
};

is same as:
1
2
3
4
5
struct Node {
	Student item;
	Node *next;
	Node(Student);
};



You are writing C++. It is recommended to use std::string, not C-strings. For example:
1
2
3
4
5
6
7
8
9
10
11
struct Student {		
	std::string name;
   	std::string id;
	std::string course;
};

// std::string has operator==
std::string inputid = ...;

if ( idPTR->id == inputid ) {
  // ... 



But what is going on here?
1
2
3
4
5
6
7
8
9
10
bool search( Node *head, Student *idPTR, char inputid, int& position )
{
	Node *current = head;
	while (current != NULL)
	{
		if (strcmp(idPTR->id, inputid)==1)
			return true;
                idPTR= idPTR->next; 
	}
}

Is this supposed to find something from a list? Which list? Is 'head' a Node in a list?
If it is, then what is the 'idPTR'? Apart from type error, why do you start with 'head', but do everything with 'idPTR'?

What is the 'position', which is not used in the function?

Note that 'inputid' is a char, but Student::id is an array char [12]. You can't compare one char with an array.

Stripping out the odd bits:
1
2
3
4
5
6
7
8
9
10
11
bool search( Node *head, const std::string& inputid )
{
	Node *current = head;
	while ( current ) // NULL is a C macro. Null pointer converts to false implicitly
	{
		if ( current->item.id == inputid ) // item.id is a std::string
			return true;
                current = current->next; 
	}
  return false;  // the function must return a value even if nothing is found
}

Last edited on
Topic archived. No new replies allowed.