Linked List w/ Class and Array of Characters

Posted 19 February 2008 - 03:27 PM

I am trying to write a program which reads in data from a file and puts it into a linked list, in the form of nodes. Then, the user inputs one of the data types in the node. I have to find all of the nodes that have that criteria, and output them in ascending order. This is an assignment, so there are some basic stipulations that I am having trouble with. Firstly, we have to use a class--which is not a problem. Secondly, we cannot use the STL library, and thirdly, we must read in all data in the form of arrays of characters. (My biggest problem by far). Here is my code:

main.cpp

/*Description: This program reads in data in a specified format from a file,
and places the information in a linked list using a node format.
The linked nodes are then put into ascending order, based on one
of the criteria in the file. The user then inputs a specific search
based on one of two of the criteria, and all node information
containing data corresponding to that specific criteria is output.
Precondition: The student.data file contains data in the correct format, the
specified sizes of the information is correct
Postcondition: The result of this program is an output of all nodes (or all
student information) corresponding to the major/class input by the
user. If the file is invalid, or the user opts to exit the program,
nothing is done, and error messages are provided.
Implementation: This program reads in data sets corresponding to a student in the form
of a node, as specified in the private data of a class, and then into a linked
list. This class contains functions to determine if values exist in the linked
list, sorts the data based on one of the node criteria, searches the linked list
for nodes that contain data corresponding to user input, and outputs these nodes.
*/
#include <iostream> //system libraries
#include <fstream> //use to read in data from file
#include "List.h" //header file for corresponding class
using namespace std;
int main()
{ List first; //list identifier
char input[4]; //type of search the user wants to be performed (max size = 4, including terminating character)
char search[3]; //specific item to search for in the linked list
char IDNumber_[10];
char lname_[31];
char fname_[31];
char major_[3];
char year_[3];
ifstream indata; //ifstream to obtain data from file
string filename; //filename specification
filename = "student.data"; //identify filename
indata.open(filename.c_str()); //open file
if(!indata.is_open()){ //determine if file opened successfully
cout<<"student.data file cannot be opened."<<endl; //if it didn't open successfully, output error message
return 0;} //if the file cannot be opened, the program cannot run, so return
first.numNodes(); //use class function to determine how many nodes are in the file
while(!first.isEmpty()){ //if the list is not empty, read in data by doing the following:
for(int i=0; i<= first.numNodes(); i++) //loop to read in data until all data is found
indata>>IDNumber_>>lname_>>fname_>>major_>>year_;
first.push(IDNumber_, lname_, fname_, major_, year_); //push new node with these criteria onto the list
}
first.bubbleSort(); //sort the list based on student last name, so it will already be ordered when output
cout<<"Total number of student records in file student.data: "<<first.numNodes()<<endl; //output number of student files
cout<<"Search for major(m) or class(c) or end to end program: "; //prompt user for type of search to perform
cin>>input; //read in type of search to perform
if(input == "M" || input == "m"){ //since the input can be lower or uppercase, allow for both, and do the following if major search:
cout<<"Enter major to search for: "; //prompt user for specific search criteria
cin>>search; //read in major for comparison to list
while(!first.isEmpty()){ //while data is still in the file, do the following
for(int i=0; i<=first.numNodes(); i++){ //use loop to search through all data in file
first.searchMajor(search)} //call function to search for data in file
}
}
else if(input == "C" || input == "c"){ //since the input can be lower or uppercase, allow for both, and do the following if class search:
cout<<"Enter class to search for: "; //prompt user for specific search criteria
cin>>search; //read in class for comparison to list
while(!first.isEmpty()){ //while data is still in the file, do the following:
for(int i=0; i<=first.numNodes(); i++){ //use loop to search through all data in file
first.searchClass(search)} //call function to search for data in file
}
}
else //if M, m, C, or c is not input, no search can be performed. end program.
return 0;
}

List.cpp

#include <iostream>
#include "List.h"
List::List() //constructor
{
top = 0; //initializes the linked list to be empty, top pointing to NULL
}
List::~List() //destructor
{
while(!isEmpty()){ //if the list is not empty, do the following:
Node *p = top->next; //the node p contains next item in list
delete top; //delete the current item
top = p; //set the next value as the current
}
}
void List::push(char IDNumber_, char lname_, char fname_[], char major_[], char year_[])
{
if(top == NULL){ //if the top pointer is NULL, input all data into a new node, but set next pointer to NULL
Node *p = new Node; //dynamically allocate space for a new node
p->IDNumber = IDNumber_; //assign input data to node
p->lname = lname_; //assign input data to node
p->fname = fname_; //assign input data to node
p->major = major_; //assign input data to node
p->year = year_; //assign input data to node
p->next = NULL; //since only one node is in the data, set the next value to NULL
top = p;} //set p to be the top and current node
else{
Node *p = new Node; //dynamically allocate space for a new node
p->IDNumber = IDNumber_; //assign input data to node
p->lname = lname_; //assign input data to node
p->fname = fname_; //assign input data to node
p->major = major_; //assign input data to node
p->year = year_; //assign input data to node
p->next = top; //make the next value of the node be the current
top = p; //set p to be the current node
}
}
void List::bubbleSort() //sort data in ascending order by student last name
{
Node *p = top; //set p to be the first node
Node *q = p->next; //set qu to be the second node
for(int i = 0; i< numNodes() - 1; i++){ //use loop to go through entire list (total = numNodes)
for(int j = 0; j< (numNodes() - i - 1); j++){ //use loop to go through list up to where list has already been sorted
if(p->lname > q->lname){ //if the first last name is greater than the second last name
swap(p, q); //swap to place in ascending order
}
p = p->next; //set p to be the next node after previous p
q = q->next; //set q to be the next node after previous q
}
p = top; //set p to be the first node again for loop
q = p->next; //set q to be the second node again for loop
}
}
char List::searchMajor(char v[]) //search list for specified criteria, and output matching node
{
Node *p = top; // use p to represent a node
while(p != 0){ //as long as the pointer is not at the end of the list,
if(p->major == v){//if the data in the node is equal to the criteria
cout<<"\n\tID number\t"<<p->IDNumber<<endl; //output node data
cout<<"\n\tLast name\t"<<p->lname; //output node data
cout<<"\n\tFirst name\t"<<p->fname; //output node data
cout<<"\n\tMajor\t"<<p->major; //output node data
cout<<"\n\tClass\t"<<p->year;} //output node data
else //if data in node does not equal criteria
p = p->next; //proceed to next node for checking
}
return 1; //return 1 if criteria is not found
}
char List::searchClass(char v); //search list for specified criteria, and output matching node
{
Node *p = top; // use p to represent a node
while(p != 0){ //as long as the pointer is not at the end of the list,
if(p->year == v){//if the data in the node is equal to the criteria
cout<<"\n\tID number\t"<<p->IDNumber<<endl; //output node data
cout<<"\n\tLast name\t"<<p->lname; //output node data
cout<<"\n\tFirst name\t"<<p->fname; //output node data
cout<<"\n\tMajor\t"<<p->major; //output node data
cout<<"\n\tClass\t"<<p->year;} //output node data
else //if data in node does not equal criteria
p = p->next; //proceed to next node for checking
}
return 1; //return 1 if criteria is not found
}
int List::numNodes() //counts the number of nodes in the list
{
Node *p = top; //use this node p to represent an item in the list
int count = 0; //initialize count of nodes to zero
while(p != 0){ //use loop to traverse through entire file (while p is not NULL, indicating end)
p = p->next; //move p through list to next node
count++; //increment count
}
return count; //return value of count once entire file has been checked
}
void List::swap(Node *first, Node *second) //swap two items in the list, based on bubblesort
{
char temp[31] = first->lname; //use temp variable to hold data in first
first->lname = second->lname; //assign data in second to first
second->lname = temp; //assign data held in temp to second
}
bool List::isEmpty(){
return top == 0;
}

I have really messed something up with the arrays of characters, and am missing something stupid. I keep getting the error:
"cannot convert from char[] to char[10]" and so on. Any suggestions anybody has about how to fix this, or anything else about my program would be greatly appreciated!

Replies To: Linked List w/ Class and Array of Characters

Re: Linked List w/ Class and Array of Characters

Posted 20 February 2008 - 12:11 PM

JJ291, on 19 Feb, 2008 - 03:27 PM, said:

I am trying to write a program which reads in data from a file and puts it into a linked list, in the form of nodes. Then, the user inputs one of the data types in the node. I have to find all of the nodes that have that criteria, and output them in ascending order. This is an assignment, so there are some basic stipulations that I am having trouble with. Firstly, we have to use a class--which is not a problem. Secondly, we cannot use the STL library, and thirdly, we must read in all data in the form of arrays of characters. (My biggest problem by far).

I have really messed something up with the arrays of characters, and am missing something stupid. I keep getting the error:
"cannot convert from char[] to char[10]" and so on. Any suggestions anybody has about how to fix this, or anything else about my program would be greatly appreciated!

First of all, you have allot of syntax errors.
You forgot to define swap() in your List.h
You did not terminate several loops.
There are alot of other things that I noticed but I got your code to compile.

main.cc

/*Description: This program reads in data in a specified format from a file,
and places the information in a linked list using a node format.
The linked nodes are then put into ascending order, based on one
of the criteria in the file. The user then inputs a specific search
based on one of two of the criteria, and all node information
containing data corresponding to that specific criteria is output.
Precondition: The student.data file contains data in the correct format, the
specified sizes of the information is correct
Postcondition: The result of this program is an output of all nodes (or all
student information) corresponding to the major/class input by the
user. If the file is invalid, or the user opts to exit the program,
nothing is done, and error messages are provided.
Implementation: This program reads in data sets corresponding to a student in the form
of a node, as specified in the private data of a class, and then into a linked
list. This class contains functions to determine if values exist in the linked
list, sorts the data based on one of the node criteria, searches the linked list
for nodes that contain data corresponding to user input, and outputs these nodes.
*/
#include <iostream> //system libraries
#include <fstream> //use to read in data from file
#include "List.h" //header file for corresponding class
using namespace std;
int main()
{ List first; //list identifier
char input[4]; //type of search the user wants to be performed (max size = 4, including terminating character)
char search[3]; //specific item to search for in the linked list
char IDNumber_[10];
char lname_[31];
char fname_[31];
char major_[3];
char year_[3];
ifstream indata; //ifstream to obtain data from file
string filename; //filename specification
filename = "student.data"; //identify filename
indata.open(filename.c_str()); //open file
if(!indata.is_open()){ //determine if file opened successfully
cout<<"student.data file cannot be opened."<<endl; //if it didn't open successfully, output error message
return 0;} //if the file cannot be opened, the program cannot run, so return
first.numNodes(); //use class function to determine how many nodes are in the file
while(!first.isEmpty()){ //if the list is not empty, read in data by doing the following:
for(int i=0; i<= first.numNodes(); i++) //loop to read in data until all data is found
indata>>IDNumber_>>lname_>>fname_>>major_>>year_;
first.push(IDNumber_, lname_, fname_, major_, year_); //push new node with these criteria onto the list
}
first.bubbleSort(); //sort the list based on student last name, so it will already be ordered when output
cout<<"Total number of student records in file student.data: "<<first.numNodes()<<endl; //output number of student files
cout<<"Search for major(m) or class(c) or end to end program: "; //prompt user for type of search to perform
cin>>input; //read in type of search to perform
if(input == "M" || input == "m"){ //since the input can be lower or uppercase, allow for both, and do the following if major search:
cout<<"Enter major to search for: "; //prompt user for specific search criteria
cin>>search; //read in major for comparison to list
while(!first.isEmpty()){ //while data is still in the file, do the following
for(int i=0; i<=first.numNodes(); i++){ //use loop to search through all data in file
first.searchMajor(search);
} //call function to search for data in file
}
}
else if(input == "C" || input == "c"){ //since the input can be lower or uppercase, allow for both, and do the following if class search:
cout<<"Enter class to search for: "; //prompt user for specific search criteria
cin>>search; //read in class for comparison to list
while(!first.isEmpty()){ //while data is still in the file, do the following:
for(int i=0; i<=first.numNodes(); i++){ //use loop to search through all data in file
first.searchClass(search);
} //call function to search for data in file
}
}
else //if M, m, C, or c is not input, no search can be performed. end program.
return 0;
}

#include <iostream>
#include "List.h"
using namespace std;
List::List() //constructor
{
top = 0; //initializes the linked list to be empty, top pointing to NULL
}
List::~List() //destructor
{
while(!isEmpty()){ //if the list is not empty, do the following:
Node *p = top->next; //the node p contains next item in list
delete top; //delete the current item
top = p; //set the next value as the current
}
}
void List::push(char IDNumber_[], char lname_[], char fname_[], char major_[], char year_[])
{
if(top == NULL){ //if the top pointer is NULL, input all data into a new node, but set next pointer to NULL
Node *p = new Node; //dynamically allocate space for a new node
p->IDNumber = IDNumber_; //assign input data to node
p->lname = lname_; //assign input data to node
p->fname = fname_; //assign input data to node
p->major = major_; //assign input data to node
p->year = year_; //assign input data to node
p->next = NULL; //since only one node is in the data, set the next value to NULL
top = p;} //set p to be the top and current node
else{
Node *p = new Node; //dynamically allocate space for a new node
p->IDNumber = IDNumber_; //assign input data to node
p->lname = lname_; //assign input data to node
p->fname = fname_; //assign input data to node
p->major = major_; //assign input data to node
p->year = year_; //assign input data to node
p->next = top; //make the next value of the node be the current
top = p; //set p to be the current node
}
}
void List::bubbleSort() //sort data in ascending order by student last name
{
Node *p = top; //set p to be the first node
Node *q = p->next; //set qu to be the second node
for(int i = 0; i< numNodes() - 1; i++){ //use loop to go through entire list (total = numNodes)
for(int j = 0; j< (numNodes() - i - 1); j++){ //use loop to go through list up to where list has already been sorted
if(p->lname > q->lname){ //if the first last name is greater than the second last name
swap(p, q); //swap to place in ascending order
}
p = p->next; //set p to be the next node after previous p
q = q->next; //set q to be the next node after previous q
}
p = top; //set p to be the first node again for loop
q = p->next; //set q to be the second node again for loop
}
}
char List::searchMajor(char v[]) //search list for specified criteria, and output matching node
{
Node *p = top; // use p to represent a node
while(p != 0){ //as long as the pointer is not at the end of the list,
if(p->major == v){//if the data in the node is equal to the criteria
cout<<"\n\tID number\t"<<p->IDNumber<<endl; //output node data
cout<<"\n\tLast name\t"<<p->lname; //output node data
cout<<"\n\tFirst name\t"<<p->fname; //output node data
cout<<"\n\tMajor\t"<<p->major; //output node data
cout<<"\n\tClass\t"<<p->year;} //output node data
else //if data in node does not equal criteria
p = p->next; //proceed to next node for checking
}
return 1; //return 1 if criteria is not found
}
char List::searchClass(char v[]) //search list for specified criteria, and output matching node
{
Node *p = top; // use p to represent a node
while(p){ //as long as the pointer is not at the end of the list,
if( p->year == v ){//if the data in the node is equal to the criteria
cout<<"\n\tID number\t"<<p->IDNumber<<endl; //output node data
cout<<"\n\tLast name\t"<<p->lname; //output node data
cout<<"\n\tFirst name\t"<<p->fname; //output node data
cout<<"\n\tMajor\t"<<p->major; //output node data
cout<<"\n\tClass\t"<<p->year; //output node data
}else{
p = p->next; //proceed to next node for checking
} // forgot to end while statement
} return 1; //return 1 if criteria is not found
}
int List::numNodes() //counts the number of nodes in the list
{
Node *p = top; //use this node p to represent an item in the list
int count = 0; //initialize count of nodes to zero
while(p != 0){ //use loop to traverse through entire file (while p is not NULL, indicating end)
p = p->next; //move p through list to next node
count++; //increment count
}
return count; //return value of count once entire file has been checked
}
void List::swap(Node *first, Node *second) //swap two items in the list, based on bubblesort
{
char* temp = first->lname; //use temp variable to hold data in first
first->lname = second->lname; //assign data in second to first
second->lname = temp; //assign data held in temp to second
}
bool List::isEmpty(){
return top == 0;
}

I added some comments on what I changed. but for the most part you will have to see for your self.

Use logic when you see the errors the compiler spits out at you. Allot of times it gives you specific lines on where you are doing something wrong.

Also, it might be a good idea to have a nodes that point both directions plus a node for your current position.
This would make it a doubly linked list, which is good if you, for some reason, want to traverse you list the other way.