Read Txt File Into Linked List C++

Hi,
I just got started with Linked lists and i am trying to read from a txt file to linked list. This is my start attempt. I have no idea how to achieve this. Any help will be greatly appreciated. Thank you.

Last edited on

At that place are two things I'd similar y'all to consider:
one make an suspend part to append vals to lists
and
two the utilise of new instead of malloc

1) Making an append function volition let you to split up some of the piece of work and allow you to see where you are having problems better, because things achieving different goals will be in different places. As well, using a class or struct in C++ introduces that concept of abstraction and encapsulation, both extremely important and helpful concepts that I propose y'all look upwardly if you lot haven't learned them yet.

two) Using new is just easier. The only time maybe to use malloc in C++ code is for performance probably.

Yous seem to have some confusion about where to store the data. You allocate an array of 100 items in principal and you too allocate space on the heap for each item with malloc in read_file() . Since this is a linked list, you should put them all on the heap.

Accept you lot heard the phrase "garbage in / garbage out?" It means if you start with junk in your input, you'll always have junk in the output. In this program, you desire to exist 100% certain that y'all're reading and writing student_tag records correctly before you lot commencement dealing with the list.

I strongly urge you to beginning by writing read() and write() methods in student_tag to read and write 1 student:

                        1
2
                                                  bool                          student_tag::read(istream &is);                          bool                          student_tag::write(ostream &os);                      

So, temporarily change primary to this:

                        1
2
iii
4
5
half-dozen
7
                                                  int                          chief() {     student_tag student;                          while                          (student.read(cin)) {         student.write(cout);     } }                      

Work on this until y'all tin can read and write the whole input file.

One time yous accept these methods working, you can use them in read_file() and display() . Something like:

                        1
2
iii
4
5
6
7
8
9
x
11
12
thirteen
fourteen
fifteen
16
17
eighteen
19
xx
21
22
23
24
25
26
27
28
29
thirty
31
32
33
34
                        student_tag *read_file()                          //readfile office                          {                          int                          count;                          double                          total = 0;     cord filename =                          "test.txt";     ifstream inFile;      inFile.open up(filename.c_str());                          if                          (inFile.fail())                          // if file doesnt open successfully                          {         cout <<                          "The File was not opened successfully\n";         cout <<                          "Please cheque that the file currently exists\n";                          render                          nullptr;     }                          int                          i = 0;     student_tag *tail=nullptr;     hptr =                          nullptr;     student_tag *nptr =                          new                          student_tag;                          while                          (nptr->read(inFile))                          // until the finish of the file                          {                          if                          (tail) {            tail->next = nptr;        }                          else                          {            hptr = nptr;        }        tail = nptr;        nptr =                          new                          student_tag;                          // create space for the adjacent one                          }                          // You created space for the i that failed to read. Delete it                          delete                          nptr;    inFile.close();                          //close file                          return                          hptr; }                      

See how nicely this divides the code? Now read_file() is almost entirely about calculation items to the list while student_tag::read() is all about reading an item from a stream.

Hello dipeshgoyal44,

Debugging the programme should exist much the same as when yous wrote the plan. Done in small steps.

Equally dhayden said first go the plan to read the file. Yous could attempt this to get started with:

                        1
2
iii
iv
5
6
7
8
nine
10
11
12
13
fourteen
fifteen
16
17
18
xix
20
21
22
23
24
25
26
27
28
29
xxx
31
32
                                                  int                          tempReadFile(int& array_size) { 	std::string name; 	std::cord id; 	std::string courseName;                          int                          units{};                          const                          std::cord inFileName{                          "test.txt"                          };  	std::ifstream inFile(inFileName);                          if                          (!inFile) 	{ 		std::cout <<                          "\n File "                          << std::quoted(inFileName) <<                          " did non open up"                          << std::endl;                          //std::this_thread::sleep_for(std::chrono::seconds(3));  // <--- Needs header files chrono" and "thread". Optional.                          render                          1; 	}  	inFile >> proper name; 	inFile >> id; 	inFile >> courseName; 	inFile >> units;  	std::cout 		<<                          "\n Proper name: "                          << proper name 		<<                          "\northward ID: "                          << id 		<<                          "\n Course Name: "                          << courseName 		<<                          "\n Units: "                          << units;                          render                          0; }                      

From the input file of:

                                  Andy Smithe 123456 Calculator Science 101 5                              

I become this:

                                  Proper noun: Andy  ID: Smithe  Course Proper noun: 123456  Units: 0                              

If I knew what your input file looks similar this might be different. Post the input file, if big 3 or 4 records volition work, so that everyone volition know what you are working with and tin utilize the same information when testing.

You lot can add together variables to read a complete record and impress it out.

This is a quick to get the reading of the file correct then y'all tin can suit the regular read function to match And then movement on to creating the linked list.

Andy

Thanks alot guys.

here is the input file:

Zen
1101825
Computer
4
88
98
52
95
Peter
112152
Electrical
3
67
98
59
Mary
1201925
Mechanical
iv
78
55
79
75
Sherin
1201925
Civil
4
69
53
78
88

I did the same program with assortment of structure earlier and the readfile function worked fine.
here is the function that i used.

Last edited on

Just that's reading into an array. Y'all're reading into a linked list, which is a different beast.

How-do-you-do dipeshgoyal44,

When I finally figured out how to read the file your code started to make some sense.

You should delete the array you define in "principal" and not laissez passer it in the part call and remove information technology from the prototype and office definition. The program is nigh linked lists not arrays.

I finally realized that "hptr" is the "head". You can utilise "hptr" if you want, but put a annotate subsequently it to say it is the head. Information technology makes understanding what it is easier.

Next you set "hptr" to Naught when divers. "nullptr", from C++11 on, would be the better choice, but you never requite "hptr" a proper value, so your linked list has nowhere to start. Refer to dhayden's earlier lawmaking for some tips.

The line: inFile.open(filename.c_str()); . Are you saying that the compiler is not using the C++11 standards or is it that you lot are existence taught the former fashion of doing this? From C++11 on you tin can use ifstream inFile(filename); . Using a std::string works just fine. Also yous can do this in one line instead of two.

In the read function taking out the assortment will make your lawmaking much easier to work with.

Andy

That's what i am not certain about. how do i read from file into a linked list? if it is in a part what practise i render? I only can't seem to understand how data insertion into linked list works from a file.

                      1
2
iii
                      std::string value; filestream >> value;                        /* append a node containing value to you list */                                          

This is what i have then far.

Final edited on

Ok i figured out how to store data into the linked listing from file. its really really messy but i have this assignment due tomorrow and i need information technology to piece of work. And so now i am storing everything in the read function. i wanted to utilize the function @dhayden wrote only i have no idea how to implement information technology. I can impress the linked list in the read part only the consignment asks to take a carve up display function. i am not sure how to display it now. Tin can someone have a expect? Thanks and so much guys. i really appreciate all your help.

Terminal edited on

You're display function looks good, but the read function is still non right. Since you're making a good effort, I'm going to give it to you. Await this over advisedly and brand sure you lot understand it.

At that place'due south nonetheless i thing missing: the boilerplate. You could either:
- add together code to read() to compute the average once you lot've read the record, or
- remove avg from course_tag completely and compute the average in brandish() when you demand it.

In general, it'southward bad to have redundant data and the avg is redundant. The problem is that you might modify one of the grades so forget to update avg. And so I'd opt for the second method: remove avg from course_tag and compute the boilerplate in brandish

                        i
2
3
4
5
six
vii
8
nine
10
11
12
thirteen
14
15
16
17
eighteen
nineteen
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
49
50
51
52
53
54
55
56
57
58
59
sixty
61
62
63
64
65
66
67
68
69
seventy
71
72
73
74
75
76
77
78
79
lxxx
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
                                                  #include <iostream>                          #include <cord>                          #include <fstream>                          #include <iomanip>                          using                          namespace                          std;                          struct                          person_tag {     cord name;     cord id; };                          struct                          course_tag {     cord course_name;                          int                          no_of_units;                          int                          marks[4];                          double                          avg; };                          struct                          student_tag {     person_tag student_info;     course_tag course_info;     student_tag *next; };                          typedef                          struct                          student_tag Student_Tag;                          typedef                          Student_Tag *Student_TagPtr;  Student_Tag *hptr; Student_Tag *cptr; Student_Tag *nptr;                          //function protypes                          void                          menu();                          void                          read();                          void                          display_students();                          void                          read()                          //readfile function                          {     hptr = nptr = Zilch;                          //intialized to null                          string filename =                          "students.txt";     ifstream inFile(filename);                          if                          (inFile.neglect())                          // if file doesnt open successfully                          { 	cout <<                          "The File was not opened successfully\n"; 	cout <<                          "Please check that the file currently exists\due north"; 	exit(1);     }                          while                          (inFile.peek() != EOF)                          // until the end of the file                          { 	cptr =                          new                          Student_Tag;                          // Read the information into the new item                          inFile >> cptr->student_info.name; 	inFile >> cptr->student_info.id; 	inFile >> cptr->course_info.course_name; 	inFile >> cptr->course_info.no_of_units;                          for                          (int                          j = 0; j < cptr->course_info.no_of_units; j++) { 	    inFile >> cptr->course_info.marks[j]; 	}                          if                          (hptr == NULL) {                          // First detail in the list. Point hptr at it                          hptr = cptr; 	}                          else                          {                          // Not the first item, append it to the tail.                          nptr->next = cptr; 	} 	nptr = cptr;                          // Motility the tail arrow                          }     cptr->adjacent = Null;                          // set up the terminal items next pointer to Zippo                          inFile.close();                          //close file                          }                          void                          brandish() {     student_tag *ptr;     ptr = hptr;                          while                          (ptr != Zilch) { 	cout <<                          "The Student Name: "                          << ptr->student_info.proper name <<                          "  \due north"; 	cout <<                          "The Student ID: "                          << ptr->student_info.id <<                          "  \n"; 	cout <<                          "The class name: "                          << ptr->course_info.course_name <<                          "  \n"; 	cout <<                          "Number of units "                          << ptr->course_info.no_of_units <<                          "  \northward"; 	cout <<                          "Marks recieved: \n";                          for                          (int                          j = 0; j < ptr->course_info.no_of_units; j++) { 	    cout << ptr->course_info.marks[j] <<                          "  \n"; 	} 	cout <<                          "The marks average is : "                          << ptr->course_info.avg <<                          "  \due north"; 	ptr = ptr->next;     } }                          int                          main() {     read();     cout <<                          "The linked listing is: ";     display();                          render                          0; }                      

hey @dhayden

Thanks so much for this. it looks much cleaner. Though when i compile information technology, it is printing an empty record at the end. not sure why.

Howdy dipeshgoyal44,

That could be considering of while (inFile.peek() != EOF) // until the end of the file. May non always work. Plus I found an extra infinite at the end of the input input file.

Removing the space mace information technology work correctly and find the (eof) marker at the proper time.

Andy

I checked the input file but information technology looks fine. Might be something else.

How-do-you-do dipeshgoyal44,

Looks can be deceiving.

Farther investigation establish that the terminal number (88) MUST NOT accept anything following it not even a new line.

Andy

As Andy pointed out, the trouble is that your code assumes that the data ends immediately afterwards the last record. A single infinite or new line will throw it off.

That'southward actually one reason that I suggested the read() and write() methods. Read() could return success when it read the entire record. That way an error anywhere along the style, fifty-fifty in the center of a tape, would be caught.

Here is a version with this logic added to the existing construction. After attempting to read a record, I check to see if the stream failed and exit if so.

BTW this demonstrates something that many programs don't understand: sometimes it makes sense to put the loop exit condition in the eye of the loop.

                        1
2
3
4
v
6
7
eight
nine
10
11
12
13
14
15
16
17
18
19
twenty
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
49
l
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
fourscore
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
                                                  #include <iostream>                          #include <string>                          #include <fstream>                          #include <iomanip>                          using                          namespace                          std;                          struct                          person_tag {     string proper noun;     string id; };                          struct                          course_tag {     string course_name;                          int                          no_of_units;                          int                          marks[4];                          double                          avg; };                          struct                          student_tag {     person_tag student_info;     course_tag course_info;     student_tag *next; };                          typedef                          struct                          student_tag Student_Tag;                          typedef                          Student_Tag *Student_TagPtr;  Student_Tag *hptr; Student_Tag *cptr; Student_Tag *nptr;                          //office protypes                          void                          carte du jour();                          void                          read();                          void                          display_students();                          void                          read()                          //readfile function                          {     hptr = nptr = NULL;                          //intialized to naught                          string filename =                          "students.txt";     ifstream inFile(filename);                          if                          (inFile.fail())                          // if file doesnt open up successfully                          { 	cout <<                          "The File was not opened successfully\north"; 	cout <<                          "Please check that the file currently exists\north"; 	exit(1);     }                          while                          (                            true                          )                          // until the end of the file                          { 	cptr =                          new                          Student_Tag;                          cptr->side by side = Null;                          // Read the data into the new item                          inFile >> cptr->student_info.proper name; 	inFile >> cptr->student_info.id; 	inFile >> cptr->course_info.course_name; 	inFile >> cptr->course_info.no_of_units;                          for                          (int                          j = 0; j < cptr->course_info.no_of_units; j++) { 	    inFile >> cptr->course_info.marks[j]; 	}                                                      // Did you read it okay?                            if                            (inFile.fail()) {                            delete                            cptr;                            // don't need it                            intermission; 	}                                                    // Okay, you read it. Add to the listing                          if                          (hptr == Null) {                          // First item in the list. Point hptr at it                          hptr = cptr; 	}                          else                          {                          // Not the starting time item, append information technology to the tail.                          nptr->next = cptr; 	} 	nptr = cptr;                          // Move the tail pointer                          }     inFile.close();                          //shut file                          }                          void                          display() {     student_tag *ptr;     ptr = hptr;                          while                          (ptr != Zip) { 	cout <<                          "The Student Proper noun: "                          << ptr->student_info.name <<                          "  \n"; 	cout <<                          "The Educatee ID: "                          << ptr->student_info.id <<                          "  \northward"; 	cout <<                          "The course proper noun: "                          << ptr->course_info.course_name <<                          "  \n"; 	cout <<                          "Number of units "                          << ptr->course_info.no_of_units <<                          "  \north"; 	cout <<                          "Marks recieved: \n";                          for                          (int                          j = 0; j < ptr->course_info.no_of_units; j++) { 	    cout << ptr->course_info.marks[j] <<                          "  \northward"; 	} 	cout <<                          "The marks average is : "                          << ptr->course_info.avg <<                          "  \n"; 	ptr = ptr->side by side;     } }                          int                          primary() {     read();     cout <<                          "The linked listing is: ";     display();                          render                          0; }                      

Thanks guys. everything is working fine now. Really appreciate it.

Topic archived. No new replies allowed.

caldwellallind.blogspot.com

Source: http://cplusplus.com/forum/beginner/270514/

0 Response to "Read Txt File Into Linked List C++"

Post a Comment

Iklan Atas Artikel

Iklan Tengah Artikel 1

Iklan Tengah Artikel 2

Iklan Bawah Artikel