Question on reading text file into structure.

Using linked list to do this.

  • (2 Pages)
  • +
  • 1
  • 2

15 Replies - 9218 Views - Last Post: 12 March 2010 - 09:25 PM Rate Topic: -----

#1 Riskinit  Icon User is offline

  • D.I.C Head

Reputation: 5
  • View blog
  • Posts: 157
  • Joined: 14-January 10

Question on reading text file into structure.

Posted 11 March 2010 - 06:36 PM

Basically I open a file, read it line by line and store everything into nodes.

Mary	Wilson	1234	2.99
Allen	Harris	1235	3.65
Mike	Davis	1236	2.65
Mary	Ann	1237	4.02
Allen	Brown	1238	3.65
Joe	Smith	1239	2.65



This is what I am trying to read. A string firstName, string lastName, string ID, double GPA.
Below is what I have come up with.

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

struct studentRec
{
	string lastName;
	string fistName;
	string ID;
	double GPA;
	studentRec *next;  //pointer to next item.
};

int main()
{
	studentRec *studentProfiles = NULL;  //head node set to null currently.

	ifstream datafile("StudentRecords.txt");
	if(!datafile)
	{
		cout << "Error in opening the file of profiles.";
		exit(1);
	}

	//Read the file into a linked list.
	studentRec profile; //Make an instance of studentRec, call it profile.
	cout << "The contents of the file are: " << endl;
        while(!datafile.eof())	//While not end of file keep reading next item.
        {						//Below, read in instance of lastName, firstName, ID, GPA.
			datafile >> profile.lastName >> profile.firstName >> profile.ID >> profile.GPA;
			studentProfiles.push_back(profile); //Take that instance of profile, add to node using function push_back.
        }
        datafile.close(); //Close data file, continue program.
}


The comments in the code represent what I am thinking. So please tell me what I am thinking wrong.

Basically as I see it, a linked list contains a head node, the place to start, and each node points to the next node. So I can read in item by item into an instance of my structure and then push back the amount of elements in the list. It isn't working how I wanted though.

cpp(30) : error C2679: binary '>>' : no operator found which takes a right-hand operand of type 'std::string' (or there is no acceptable conversion)


Is the fist error that comes up. However this worked fine in an older program where I was using vectors and the same method to read data into the vector. Any insight into this problem?

Any help at all would be great. Even a small tutorial on making linked list of structures like I am. Couldn't find any on google. I am still learning everything about linked lists so please be patient with me. :mellow:

Is This A Good Question/Topic? 0
  • +

Replies To: Question on reading text file into structure.

#2 n8wxs  Icon User is offline

  • --... ...-- -.. . -. ---.. .-- -..- ...
  • member icon

Reputation: 972
  • View blog
  • Posts: 3,878
  • Joined: 07-January 08

Re: Question on reading text file into structure.

Posted 11 March 2010 - 07:44 PM

Have a look at Creating Linked Lists in C++
Was This Post Helpful? 1
  • +
  • -

#3 Riskinit  Icon User is offline

  • D.I.C Head

Reputation: 5
  • View blog
  • Posts: 157
  • Joined: 14-January 10

Re: Question on reading text file into structure.

Posted 11 March 2010 - 08:44 PM

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

struct node
{
	string lastName;
	string firstName;
	string ID;
	double GPA;
	node *next;  //pointer to next item.
};

int main()
{
	node *head = NULL;  //define an initially empty linked list by defining a pointer to be used as the list starting pointer.
	head = new node;		//refer to the new node as *temp, i.e. "the node that temp points to"
	cout << "Please enter the first name of the person: ";
	cin >> head->firstName;
	cout << "Please enter the last name of the person: ";
	cin >> head->lastName;
	cout << "Please enter the user I.D. : ";
	cin >> head->ID;
	cout << "Please enter the grade point average : ";
	cin >> head->GPA;
	head->next = NULL;
}


Is what I have come up with from the tutorial you showed me, but I have a few questions.
node *head = NULL

I create a new node, type structure, and call it *head set equal to NULL. So this is saying what exactly? I guess I am still confused about pointers. It is pointing to nothing?

temp = new node;


This was the line they gave in the tutorial, but the compiler wouldn't accept it. So I changed the temp to head which worked. In this line I am creating a node, right? And calling it head?

head->next = NULL;


Finally, this causes the node I just created (head) and entered information for, and it sets the pointer in the structure equal to NULL? Basically saying end of list?


I guess I am sort of confused by all the pointers going on.
Was This Post Helpful? 0
  • +
  • -

#4 r.stiltskin  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 1833
  • View blog
  • Posts: 4,927
  • Joined: 27-December 05

Re: Question on reading text file into structure.

Posted 11 March 2010 - 09:09 PM

View PostRiskinit, on 11 March 2010 - 10:44 PM, said:

Is what I have come up with from the tutorial you showed me, but I have a few questions.
node *head = NULL

I create a new node, type structure, and call it *head set equal to NULL. So this is saying what exactly? I guess I am still confused about pointers. It is pointing to nothing?
Exactly, it is pointing to nothing.

Quote

temp = new node;


This was the line they gave in the tutorial, but the compiler wouldn't accept it. So I changed the temp to head which worked. In this line I am creating a node, right? And calling it head?

It's not that head is a magic word. When you wrote temp = new node you hadn't declared temp. If you had written
node *temp = new node;
or
node *temp;
// some other code ...
temp = new node;

that would have been fine.

Quote

head->next = NULL;


Finally, this causes the node I just created (head) and entered information for, and it sets the pointer in the structure equal to NULL? Basically saying end of list?
Correct. You can test, e.g., say you are working with a arbitrary node temp somewhere in a list:
if(temp->next!=NULL) {
// do something with the next node
}

That way, you can avoid trying to access a node that doesn't exist (which would cause your program to crash).

By the way, given what you are working on here there is no reason for #include <list> in this program. That <list> header is needed only if you want to use an STL list -- a whole different animal that you should learn about at some point (actually easier to use than creating your own linked list, but it is important for you to learn linked lists anyway).
Was This Post Helpful? 1
  • +
  • -

#5 n8wxs  Icon User is offline

  • --... ...-- -.. . -. ---.. .-- -..- ...
  • member icon

Reputation: 972
  • View blog
  • Posts: 3,878
  • Joined: 07-January 08

Re: Question on reading text file into structure.

Posted 11 March 2010 - 09:30 PM

Quote

 node *head = NULL;


It is pointing to nothing?


Yes! :)

The list is empty, there are no nodes linked to it.

So instead of head = new node; you want to do something like node *temp = new node;

Here's the add_node_at_end() from the tutorial. Notice it declares 2 temp node pointers: one to hold the new node and it's information, and the second one to use when 'walking' the list of nodes to find the end of the list.

I've modified the code to use your structure's variable names:

void add_node_at_end ()
  {  
     node *temp, *temp2;   // Temporary pointers

     // Reserve space for new node and fill it with data
     temp = new node;

     cout << "Please enter the first name of the person: ";
     cin >> temp->firstName;

     cout << "Please enter the last name of the person: ";
     cin >> temp->lastName;

     cout << "Please enter the user I.D. : ";
     cin >> temp->ID;

     cout << "Please enter the grade point average : ";
     cin >> temp->GPA;

     temp->next = NULL;

     // Set up link to this node
     if (head == NULL)  // if list is empty
         head = temp;   // become first node
     else
       { temp2 = head;  // copy the list pointer
         // We know this is not NULL - list not empty!
         while (temp2->next != NULL) // another node?
           {  temp2 = temp2->next;   // yes, copy pointer
              // Move to next link in chain
           }
         // while() loop has found end of list
         temp2->next = temp; // insert our new node as new end of list
       }
  }


Was This Post Helpful? 1
  • +
  • -

#6 Riskinit  Icon User is offline

  • D.I.C Head

Reputation: 5
  • View blog
  • Posts: 157
  • Joined: 14-January 10

Re: Question on reading text file into structure.

Posted 11 March 2010 - 09:50 PM

Quote

By the way, given what you are working on here there is no reason for #include <list> in this program. That <list> header is needed only if you want to use an STL list -- a whole different animal that you should learn about at some point (actually easier to use than creating your own linked list, but it is important for you to learn linked lists anyway).


Originally I was thinking of doing something like I did in my vector program... and use push_back in the STL list container.

Some of the functions in the container look so useful... :D
Was This Post Helpful? 0
  • +
  • -

#7 r.stiltskin  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 1833
  • View blog
  • Posts: 4,927
  • Joined: 27-December 05

Re: Question on reading text file into structure.

Posted 11 March 2010 - 10:19 PM

View PostRiskinit, on 11 March 2010 - 11:50 PM, said:

Some of the functions in the container look so useful... :D

Well, yeah... B)

But you know, since this C++, the usual thing to do, if you're writing something like a linked list, is not to just create a "head" pointer in your main function, but instead wrap that head pointer along with a constructor, destructor, and a set of useful functions to add nodes, remove nodes, search for nodes, etc, etc, just like those juicy functions you see for the STL list.
Was This Post Helpful? 0
  • +
  • -

#8 Riskinit  Icon User is offline

  • D.I.C Head

Reputation: 5
  • View blog
  • Posts: 157
  • Joined: 14-January 10

Re: Question on reading text file into structure.

Posted 12 March 2010 - 12:52 PM

Ok, back to my linked list program now that I understand pointers better.

struct studentRec
{
    string firstName_1;
    string lastName_1;
    string ID_1;
    double GPA_1;
    studentRec *next_1;
    //Constructor
    studentRec(string lastName, string firstName, string ID, double GPA, studentRec *next = NULL)
    {
		firstName_1 = firstName;
		lastName_1 = lastName;
		ID_1 = ID;
		GPA_1 = GPA;
		next_1 = next;
    }
};


This is the structure that I make to hold information about an individual. I based this off of an example in my book but want to make sure I understand the how the pointers all work.
The line following makes a variable that holds the memory address of a studentRec.
 studentRec *next_1 


Next I make a constructor which contains a bunch of variables. This code
studentRec *next = NULL
Says I am making a variable called next of type studentRec that points to nothing. So when I use this constructor I enter everthing, which is automatically converted to my structure.

Where I am having a problem is with the linked list. I can read the file in correctly, but when I go to print the linked list everything is backwards. Reads the first record last and the last record first, which makes me think I am pointing everything in the wrong direction, except in my books example everything is backwards when they print their linked list. So could someone explain my errors?

int main()
{
    studentRec *studentList = NULL;				//Pointer variable called studentList. Points to nothing initially.

    ifstream studentFile("StudentRecords.txt");	//Stream file called StudentRecords.txt.
    if(!studentFile)							//Test program availability.
    {
        cout << "\n File is corrupted!\n";
        exit(1);
    }

    string firstName_2;	//Placeholder for firstName.
    string lastName_2;	//Placeholder for lastName.
    string ID_2;		//Placeholder for ID.
    double GPA_2;		//Placeholder for GPA.

	cout << "The information in the file: \n";
    while(studentFile >> lastName_2 >> firstName_2 >> ID_2 >>GPA_2)	//Read from file a last name, first name, id, and gpa.
    {
        cout << lastName_2 << ", " << firstName_2 << "\t\t" << ID_2 << "\t\t" << GPA_2 << endl; //Output what is found.
		//Creating a node in the list. Enters information into that node. Point to next node.
        studentList = new studentRec(lastName_2, firstName_2, ID_2, GPA_2, studentList);
    }
	cout << "\nThe printed linked list is: \n";
    studentRec *ptr = studentList;
    while(ptr != NULL)
    {cout << ptr->lastName_1 << ", " << ptr->firstName_1 << "  " << ptr->ID_1 << "  " << ptr->GPA_1 << "\n";
        ptr=ptr->next_1;
    }
    return 0;
}

Was This Post Helpful? 0
  • +
  • -

#9 r.stiltskin  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 1833
  • View blog
  • Posts: 4,927
  • Joined: 27-December 05

Re: Question on reading text file into structure.

Posted 12 March 2010 - 01:26 PM

It's not that there's something wrong with your list. The list is backwards because of the way you are using it.

In this line of code
        studentList = new studentRec(lastName_2, firstName_2, ID_2, GPA_2, studentList);


you're adding each new item to the front instead of the back.

Think about that & post again if you don't see why.
Was This Post Helpful? 0
  • +
  • -

#10 Riskinit  Icon User is offline

  • D.I.C Head

Reputation: 5
  • View blog
  • Posts: 157
  • Joined: 14-January 10

Re: Question on reading text file into structure.

Posted 12 March 2010 - 01:42 PM

View Postr.stiltskin, on 12 March 2010 - 12:26 PM, said:

It's not that there's something wrong with your list. The list is backwards because of the way you are using it.

In this line of code
        studentList = new studentRec(lastName_2, firstName_2, ID_2, GPA_2, studentList);


you're adding each new item to the front instead of the back.

Think about that & post again if you don't see why.


Have you ever seen one of those drawings or paintings, and in that drawing is a hidden picture?
http://www.planetper....com/en/item184

I feel like I am looking at a drawing right now but not seeing what is important.

This is what I am thinking... I am creating a node with the necessary info, but the 5th entry is throwing me off. I pass studentList which points to nothing. And then I call this new node studentList. So something is out of place, but I am not sure. This dumb book does a poor job at teaching.
Was This Post Helpful? 0
  • +
  • -

#11 r.stiltskin  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 1833
  • View blog
  • Posts: 4,927
  • Joined: 27-December 05

Re: Question on reading text file into structure.

Posted 12 March 2010 - 02:12 PM

It's called a linked list because each node is a link in a chain. The idea is that the first node in the chain points to the second which points to the third, and so on. So a list with 4 nodes looks something like this:

N0 -> N1 -> N2 -> N3 -> [NULL == 0]

Each node has a "next-pointer" that has the memory address of the next node. When you create a new node, that new node is going to be the last one in the chain (unless you're creating a sorted list, but that's a different story), so you automatically set its next-pointer to NULL to make it explicit that it doesn't point to a real memory address.

What you have been doing is first, creating a new node that initially points to NULL, but then setting the new node's next-pointer to the address in studentList, which is the "head" of the list, and finally setting studentList to the address of the new node, thus placing the new node at the head of the list.

To add a new node at the END of the chain, you first have to find the node that's currently the end of the chain and set its next-pointer to point to the new node, and leave the pointer that points to the head of the chain (in this case studentList) unchanged, except when you are creating the FIRST node. As you can see, it is a pain (and quite inefficient) to have to search through the entire list to find the end every time you want to add a node. Therefore, in addition to the pointer to the head of the list, a list class normally also has a pointer to the "tail" (the last node in the list), and every time you add a new node you would reassign the tail pointer and also the next-pointer of the node that used to be last so that BOTH of them point to the new last node.
Was This Post Helpful? 1
  • +
  • -

#12 jjl  Icon User is offline

  • Engineer
  • member icon

Reputation: 1112
  • View blog
  • Posts: 4,619
  • Joined: 09-June 09

Re: Question on reading text file into structure.

Posted 12 March 2010 - 03:20 PM

it seems like your trying to use std::vector, hence the vector.push_back function call you make. Using a vector is quite simple if you are allowed to use them
#include <fstream>
#include <iostream>
#include <vector> //need for std::vector
#include <string>

using namespace std;

struct studentRec
{
        string lastName;
        string firstName; 
        string ID;
        double GPA;
};

int main()
{
        vector<studentRec>studentProfiles(0); //create a empty vector of studentRect;

        ifstream datafile("StudentRecords.txt");
        if(!datafile)
        {
                cerr << "Error in opening the file of profiles.";
				cin.get();
                exit(1);
        }
        studentRec profile; //Make an instance of studentRec, call it profile.
        cout << "The contents of the file are: " << endl<<endl;
        while(!datafile.eof())  //While not end of file keep reading next item.
        {                                       
			datafile >> profile.firstName>> profile.lastName>> profile.ID >> profile.GPA;
			studentProfiles.push_back(profile); //push back a new studentRec into vector                  
        }
        datafile.close(); 

		//output results
		for(int i=0;i<studentProfiles.size(); i++)
		{
			cout<<"NAME: "<<studentProfiles[i].firstName<<" "<<studentProfiles[i].lastName<<endl
				<<"ID : "<<studentProfiles[i].ID<<endl
				<<"GPA :"<<studentProfiles[i].GPA<<endl<<endl;
		}

		//pause window
		cin.ignore();
		cin.get();
		return 0;
}


Was This Post Helpful? 0
  • +
  • -

#13 r.stiltskin  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 1833
  • View blog
  • Posts: 4,927
  • Joined: 27-December 05

Re: Question on reading text file into structure.

Posted 12 March 2010 - 03:44 PM

View PostImaSexy, on 12 March 2010 - 05:20 PM, said:

it seems like your trying to use std::vector,


In all of that discussion, post after post, about how a linked list works, could you possibly read that the OP is trying to use std::vector? :gun_bandana:
Was This Post Helpful? 0
  • +
  • -

#14 jjl  Icon User is offline

  • Engineer
  • member icon

Reputation: 1112
  • View blog
  • Posts: 4,619
  • Joined: 09-June 09

Re: Question on reading text file into structure.

Posted 12 March 2010 - 03:48 PM

because i only read the first post when he was trying to use the std::vector::push_back, sorry about that lol
Was This Post Helpful? 0
  • +
  • -

#15 Riskinit  Icon User is offline

  • D.I.C Head

Reputation: 5
  • View blog
  • Posts: 157
  • Joined: 14-January 10

Re: Question on reading text file into structure.

Posted 12 March 2010 - 06:54 PM

Also, if my ultimate goal is to have the file be alphabetical by last name is this even a good approach to begin with? Once again thanks for the guidance, because I really need it.

This post has been edited by Riskinit: 12 March 2010 - 07:13 PM

Was This Post Helpful? 0
  • +
  • -

  • (2 Pages)
  • +
  • 1
  • 2