0

Hi right now I am trying to rewrite my code so it can take in each item of the linked list as a string reading a first and last name. At the moment I got the program to work, but when I enter a first and last name the program treats them as separate elements instead of one single entity. So basically I want "Jack Frost" to have a linked list length of 1 instead 2, and then I try to prompt the user to enter a first and last name so they are deleted from the list. Hopefully someone can help. I am posting the tester program I made and the header file. Fair warning the header file is a bit long. The tester program needs to print the full list line by line with first and last name.

Update: I do prompt the user to enter first and last name in the same line. They are for some reason being counted as two separate elements, I need to them to be considered on element together.

#ifndef H_LinkedListType
#define H_LinkedListType


#include <iostream>

                            //Definition of the node

template <typename Type>
struct nodeType
{
    Type info;
    nodeType<Type> *link;
};

template<typename Type>
class linkedListType
{
  public:
    const linkedListType<Type>& operator=(const linkedListType<Type>&); 
                                                               //Overload the assignment operator
    void initializeList(); 
                                   //Initialize the list to an empty state
                                   //Post: first = NULL, last = NULL
    bool isEmptyList();
                                   //Function returns true if the list is empty;
                                   //otherwise, it returns false
    bool isFullList();
                                   //Function returns true if the list is full;
                                   //otherwise, it returns false
    void print();
                                   //Output the data contained in each node
                                   //Pre: List must exist
                                   //Post: None
    int length();
                                   //Return the number of elements in the list
    void destroyList();
                                   //Delete all nodes from the list
                                   //Post: first = NULL, last = NULL
    void retrieveFirst(Type& firstElement); 
                                   //Return the info contained in the first node of the list
                                   //Post: firstElement = first element of the list
    void search(const Type& searchItem);
                                   //Outputs "Item is found in the list" if searchItem is in 
                                   //the list; otherwise, outputs "Item is not in the list"
    void insertFirst(const Type& newItem);
                                   //newItem is inserted in the list
                                   //Post: first points to the new list and the 
                                   //       newItem inserted at the beginning of the list
    void insertLast(const Type& newItem);
                                   //newItem is inserted in the list
                                   //Post: first points to the new list and the 
                                   //     newItem is inserted at the end of the list
                                   //     last points to the last node in the list
    void deleteNode(const Type& deleteItem);
                                   //if found, the node containing deleteItem is deleted 
                                   //from the list
                                   //Post: first points to the first node and
                                   //  last points to the last node of the updated list
    linkedListType(); 
                                   //default constructor
                                   //Initializes the list to an empty state
                                   //Post: first = NULL, last = NULL 
    linkedListType(const linkedListType<Type>& otherList); 
                                   //copy constructor
    ~linkedListType();   
                                   //destructor
                                   //Deletes all nodes from the list
                                   //Post: list object is destroyed 

  protected:
    nodeType<Type> *first;                             //pointer to the first node of the list
    nodeType<Type> *last;                              //pointer to the last node of the list 
};

template<typename Type>
void linkedListType<Type>::initializeList()
{
    destroyList();                             //if the list has any nodes, delete them
}

template<typename Type>
void linkedListType<Type>::print()
{
    nodeType<Type> *current;                             //pointer to traverse the list

    current = first;                               //set current so that it points to 
                                                   //the first node
    while(current != NULL)                             //while more data to print
    {
       cout<<current->info<<" ";
       current = current->link;
    }
}                            //end print

template<typename Type>
int linkedListType<Type>::length()
{
    int count = 0;
    nodeType<Type> *current;                             //pointer to traverse the list

    current = first;

    while (current!= NULL)
      {
       count++;
       current = current->link;
    }

    return count;
}                              // end length

template<typename Type>
void linkedListType<Type>::search(const Type& item)
{
    nodeType<Type> *current;                             //pointer to traverse the list
    bool found;

    if(first == NULL)                              //list is empty
        cout<<"Cannot search an empty list. "<<endl;
    else
    {
        current = first;                              //set current pointing to the first 
                                                      //node in the list

        found = false;                                //set found to false

        while(!found && current != NULL)                             //search the list
            if(current->info == item)                                  //item is found
                found = true;
            else
                current = current->link;                             //make current point to 
                                                                     //the next node

        if(found)
            cout<<"Item is found in the list."<<endl;
        else
            cout<<"Item is not in the list."<<endl;
   }                             //end else
}                            //end search

template<typename Type>
void linkedListType<Type>::insertLast(const Type& newItem)
{
    nodeType<Type> *newNode;                             //pointer to create the new node

    newNode = new nodeType<Type>;                             //create the new node
    newNode->info = newItem;                                  //store the new item in the node
    newNode->link = NULL;                                     //set the link field of new node
                                                              //to NULL

    if(first == NULL)                              //if the list is empty, newNode is 
                                                //both the first and last node
    {
        first = newNode;
        last = newNode;
    }
    else                                 //if the list is not empty, insert newNnode after last
    {
        last->link = newNode;                             //insert newNode after last
        last = newNode;                             //make last point to the actual last node
    }
}                            //end insertLast

template<typename Type>
void linkedListType<Type>::deleteNode(const Type& deleteItem)
{
    nodeType<Type> *current;                             //pointer to traverse the list
    nodeType<Type> *trailCurrent;                             //pointer just before current
    bool found;

    if(first == NULL)                                //Case 1; list is empty. 
        cout<<"Can not delete from an empty list.\n";
    else
    {
        if(first->info == deleteItem)                             //Case 2 
        {
            current = first;
            first = first ->link;
            if(first == NULL)                                //list had only one node
                last = NULL;
            delete current;
        }
        else                              //search the list for the node with the given info
        {
            found = false;
            trailCurrent = first;                               //set trailCurrent to point to
                                                                //the first node
            current = first->link;                              //set current to point to the 
                                                                //second node

            while((!found) && (current != NULL))
            {
                if(current->info != deleteItem) 
                {
                    trailCurrent = current;
                    current = current-> link;
                }
                else
                    found = true;
            }                                           // end while

            if(found)                                                   //Case 3; if found, delete the node
            {
                trailCurrent->link = current->link;

                if(last == current)                                     //node to be deleted was 
                                                                        //the last node
                    last = trailCurrent;                                //update the value of last

                delete current;                                         //delete the node from the list
            }
            else
                cout<<"Item to be deleted is not in the list."<<endl;
        }                             //end else
    }                             //end else
}                             //end deleteNode

#endif

This is the tester program below.

//This program tests various operation of a linked list

#include "stdafx.h"
#include <string>//Need to import string to the class to be able to use that type
#include <iostream>
#include "linkedList.h"

using namespace std;

int main()
{
    linkedListType<string> list1, list2;                
    int num;
    string name;//Input from the user


    //cout<<"Enter numbers ending with -999"
        //<<endl;                                       
    //cin>>num; 

    cout<<"Please enter first and last name in each line, enter end to close program" //Prompting the user to enter first and last name on each line til they specify "end"
        <<endl;
        cin>>name;

    while(name != "end")//Checks if user entered name if not it will proceed to keep prompting the user                                 
    {
        list1.insertLast(name);//inserts the name at the end of the list                        
        cin>>name;                                  
    }

    cout<<endl;                                     

    cout<<"List 1: ";                       
    list1.print();//Prints all the names line by line                                   
    cout<<endl;                                     
    cout<<"Length List 1: "<<list1.length()//Gives length of how many names are in the list 
        <<endl;                                     

    list2 = list1;                                  //test the assignment operator 

    cout<<"List 2: ";                       
    list2.print();                                  
    cout<<endl;                                     
    cout<< "Length List 2: "<< list2.length()   <<endl;                                     

    cout<< "Enter the name to be "  << "deleted: ";                             
    cin>>num;                                       
    cout<<endl;                                     

    list2.deleteNode(name);                         

    cout<<"After deleting the node, "
        << "List 2: "<<endl;                            
    list2.print();                                  
    cout<<endl;                                     

    cout<<"Length List 2: "<<list2.length()
        <<endl;                                     

    system("pause");

    return 0;   
10
  • 1
    And what was your question again please? Commented Jul 15, 2014 at 19:32
  • 1
    This might be helpful for understanding: stackoverflow.com/questions/23047052/… Commented Jul 15, 2014 at 19:39
  • 1
    FYI: Dialogue in your data structures is bad, mmK. Commented Jul 15, 2014 at 19:55
  • 1
    @FinalContest Tons of code, not debugging efforts or even attempts? Commented Jul 16, 2014 at 6:32
  • 1
    @FinalContest Reread this section from the help center and honestly judge, if the question meets all these points (the debugging part in particular). Commented Jul 16, 2014 at 7:06

3 Answers 3

3

cin input is separated also with space, in your sample code, in the last loop when read cin>>name; name would take value for all spaces and new line separated words.

Use this instead:

std::string name;

std::getline(std::cin, name);
Sign up to request clarification or add additional context in comments.

5 Comments

I don't believe the OP's issue is with reading strings, but rather how to put more than one field into a linked list node without modifying the linked list code.
@ThomasMatthews on the contrary, I think it is a problem with reading. It the user naively hits space between first and last name, you get two different reads, which ends up being two different link nodes. While it should be a class or struct with two fields, they still need to read them correctly.
should be good to have a class or struct but i thinks it's better read by line because first and/or last name could have in total more than 2 word and there will be problems with the read logic, even reading all the line the split point problem remain but at least the complete name is read OK.
I tried this method, but now its not counting anything as apart of the lists and is returning a length 0.
I an getting the right name read, but and exception (Tested GCC 4.9.0). In VS2013 work OK insertion but have an error in deletion cout<< "Enter the name to be " << "deleted"; cin>>num; cout<<endl; list2.deleteNode(name); num is read and name is use for the call (name in this point is always 'end')
1

The easiest solution is to create a structure containing your two strings:

struct Person_Name
{
  std::string first;
  std::string last;
};

Then you can "pass" the structure as the type in your linked list:

LinkedListType<Person_Name> people;

You may have to adjust the "genericity" or assumptions made by the list or add functionality to the Person_Name to make it conform to the list's interface.

Edit 1: Comparing the data
The linked list is probably using operator< to order the nodes in the list. So you will have to add that overloaded operator to your structure:

struct Person_Name
{
  std::string first_name;
  std::string second_name;
  bool operator<(const& Person_Name pn) const
  {
    if (second_name == pn.second_name)
    {
       return first_name < pn.first_name;
    }
    return second_name < pn.second_name;
  }
};

You can implement operator== in a similar fashion.

1 Comment

This is a linked list class the OP is building, and there is nothing in the code posted above that deals with comparison or sorting (although this would be a better way to store the data than just one single std::string).
1

Instead of name and surname in two lines get them in one line as following:

char name[256]
std::cout << "Please, enter your name: and surname";
std::cin.getline (name,256);

To split name and surname copy/paste this code to your solution.

std::vector<std::string> &split(const std::string &s, char delim, std::vector<std::string> &elems) {
    std::stringstream ss(s);
    std::string item;
    while (std::getline(ss, item, delim)) {
        elems.push_back(item);
    }
    return elems;
}

std::vector<std::string> split(const std::string &s, char delim) {
    std::vector<std::string> elems;
    split(s, delim, elems);
    return elems;
}

Then divide name and surname you will write

vector<string> person = split(name, ' ');
person.at(0)  // the name of the person 
person.at(1)  //the surname of the person

6 Comments

See I am prompting the entire name in one line, but when running the program even though they are added in one line to the list they are still considered two different elements even though i want them to be treated as one. I need to enter them in a list
By this line, it will not consider as two seperate users. cout << "enter name and surname" doesn't mean anything, cin is the thing what reads the line or word. By this, you will read line not word
You are promting, but your code does not read it that way. using cin >> name; will ignore whitespace, get the string typed, then stop after any whitespace, leaving the rest until another call.
How does one separate the first name from the surname using your example?
I added split method. With this method you can get name and surname separated.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.