I need to read in instructions from a file, then with those instructions, insert the names and scores below the instruction into a linked lists. I've tried using getline, and >> and I keep getting errors. Here is what I have so far:

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

class LinkedList
{
private:	
	struct Node
	{
		string name;
		int number;	
		struct Node *next;
	};


	Node *head;

public:
	LinkedList()
		{head = NULL; }
	void addLast(string, int);
	void Insert(string, int);
	void Delete(string, int);
	void Display() const;
};

void LinkedList::addLast(string data1, int data2)
{
	Node *newNode;
	Node *nodePtr;
	
	newNode = new Node;
	newNode->name = data1;
	newNode->number = data2;
	newNode->next = NULL;

	if (!head)
		head = newNode;
	else
	{
		nodePtr = head;
		while (nodePtr->next)
			nodePtr = nodePtr->next;
		nodePtr->next = newNode;
	}
}

void LinkedList::Insert(string data1, int data2)
{
	int comp;
	Node *newNode;
	Node *nodePtr;
	Node *prevNode = NULL;

	newNode = new Node;
	newNode->name = data1;
	newNode->number = data2;
	
	if(!head)
	{
		head = newNode;
		newNode->next = NULL;
	} 
	else
	{
		nodePtr = head;
		prevNode = NULL;
	
		while((nodePtr != NULL) && (nodePtr->name.compare(data1) < 0))
		{
			prevNode = nodePtr;
			nodePtr = nodePtr->next;
		}

		if(prevNode == NULL)
		{
			head = newNode;
			newNode->next = nodePtr;
		}
		else 
		{
			prevNode->next = newNode;
			newNode->next = nodePtr;
		}
	}
}

void LinkedList::Delete(string data1, int data2)
{
	int comp;
	Node *nodePtr;
	Node *prevNode;
	
	if(!head)
		return;

	
	if(nodePtr->name.compare(data1) == 0)
	{
		nodePtr = head-> next;
		delete head;
		head = nodePtr;
	}
	else
	{
		nodePtr = head;
		while((nodePtr != NULL) && (nodePtr->name.compare(data1) != 0))
		{
			prevNode = nodePtr;
			nodePtr = nodePtr-> next;
		}

		if(nodePtr)
		{
			prevNode->next = nodePtr->next;
			delete nodePtr;
		}
	}
}		

void LinkedList::Display() const
{
	Node *nodePtr;
	nodePtr = head;

	while(nodePtr)
	{
		cout << nodePtr->name << nodePtr->number << endl;
		nodePtr = nodePtr->next;
	}
}

int main()
{
	ifstream inFile;
	const int SIZE = 51;
	string nm, info[SIZE], input, num;
	char ch;
	int i = 0;

	inFile.open("/home/sgilbert/Documents/scores.txt");
	if(!inFile)
	{
		cout << "Error! File cannot open." << endl;
		return 0;
	}
	else
		cout << "File has been opened." << endl;

	inFile >> input;
	while(!inFile.eof())
	{
		if (input == "%INSERT")
		{
			while(input != "%DELETE")
			{
				inFile >> nm;
				inFile >> num;
				cout << nm << num << endl;
			}
		}
		else if (input == "%DELETE")
		{
			cout << "delete" << endl;
		}
		else if (input == "%SEARCH")
		{
			cout << "search" << endl;
		}
		else if (input == "%PRINT")
			cout << "print" << endl;
		else if (input == "%END")
			return 0;

	cout << "File has been closed." << endl;
	return 0;

I'm working on this program in steps, and when I output the values I just put in for the %INSERT function, I get %PRINT in a loop.
My program also skips over the first line of the file. It doesn't recognize it.
The File is:
%INSERT
MARK 29
DAVID 21
JOHN 44
JOHN 51
LARRY 39
MARK 21
DAVID 18
JOHN 28
MARK 35
DONALD 41
PHIL 26
%PRINT
%DELETE
MARK
DAVID
%PRINT
%SEARCH
JONE
DAVID
LARRY
%INSERT
LARRY 13
GARY 15
GARY 42
%PRINT
%INSERT
TERRY 23
%DELETE
GARFIELD
%SEARCH
PHIL
%PRINT
%END

if (input == "%INSERT")
		{
			while(input != "%DELETE")
			{
				inFile >> nm;
				inFile >> num;
				cout << nm << num << endl;
			}
		}

This looks like an infinite loop. You establish at first that input is %INSERT, and then you keep reading in for as long as input does not equal %DELETE, but you never change input, so it will always be %INSERT and the while loop will never end.

Edited 4 Years Ago by Moschops: n/a

if (input == "%INSERT")
		{
			while(input != "%DELETE")
			{
				inFile >> nm;
				inFile >> num;
				cout << nm << num << endl;
			}
		}

This looks like an infinite loop. You establish at first that input is %INSERT, and then you keep reading in for as long as input does not equal %DELETE, but you never change input, so it will always be %INSERT and the while loop will never end.

So how do I continue reading in a new input and still get the names and scores from the file?
I tried this:

while(input != "%DELETE")
                        {
                                inFile >> input;
                                nm = input;
                                inFile >> input;
                                num = input;
                                cout << nm << num << endl;
                        }

but still no luck.

The crux of it is you've just got your logic of how to deal with it wrong. You need to step back, stop poking at the code, and rethink how to do it.

Edited 4 Years Ago by Moschops: n/a

>>So how do I continue reading in a new input and still get the names and scores from the file?

Read the file line by line using getline.
Look at the fist char of the line read in.
If it's an '%' the line is an instruction so find the instruction and do what needs to be done per implementation of that instruction
If not, its a name and beak the line up into the name and the number using a stringstream. You can then use the name to search or delete or change the information in the node, whatever.

>>So how do I continue reading in a new input and still get the names and scores from the file?

Read the file line by line using getline.
Look at the fist char of the line read in.
If it's an '%' the line is an instruction so find the instruction and do what needs to be done per implementation of that instruction
If not, its a name and beak the line up into the name and the number using a stringstream. You can then use the name to search or delete or change the information in the node, whatever.

I thought about that first but once the program reads the instruction, it needs to continue reading in the names and scores so that it can insert them, delete them, etc in the linked list.

Not a problem. The program could be basically one big loop with a loop in each subroutine that needs it so it can read in more than one line if needed:

bool keepRunning = true
string temp;

read in first line to temp

while keepRunning
  if temp is %insert
   read next line into temp
   while first char of temp is not %
      use stringtream to break temp up and create new node
      insert node into list
      read next line into temp
  else if temp is %search
   read next line into temp
   while first char of temp is not %
      use stringtream to break temp up   
      use another loop to search list for node with information from temp
        if information in temp found
         do something
      read next line into temp
  ...
  else if temp is %EXIT
    change keepRunning to false

You will need to expand the if/else if statements to include all instruction options. You may want to use other types of loops depending on your comfort level. Etc. But this type of schematic should work.

This article has been dead for over six months. Start a new discussion instead.