开发者

Reading input from a text file, omits the first and adds a nonsense value to the end?

开发者 https://www.devze.com 2022-12-25 02:46 出处:网络
When I input locations from a txt file I am getting a peculiar error where it seems to miss off the first entry, yet add a garbage entry to the end of the link list (it is designed to take the name, l

When I input locations from a txt file I am getting a peculiar error where it seems to miss off the first entry, yet add a garbage entry to the end of the link list (it is designed to take the name, latitude and longitude for each location you will notice). I imagine this to be an issue with where it starts collecting the inputs and where it stops but I cant find the error!! It reads the first line correctly but then skips to the next before adding it because during testing for the bug it had no record of the first location Lisbon though whilst stepping into the method call it was reading it. Very bizarre but hopefully someone knows the issue. Here is firstly my header file:

#include <string>

struct locationNode
{
    char nodeCityName [35];
    double nodeLati;
    double nodeLongi;

    locationNode* Next;



void CorrectCase() // Correct upper and lower case letters of input
    {

        int MAX_SIZE = 35;
        int firstLetVal = this->nodeCityName[0], letVal;
        int n = 1; // variable for name index from second letter onwards


        if((this->nodeCityName[0] >90) && (this->nodeCityName[0] < 123)) // First letter is lower case
        { 
             firstLetVal = firstLetVal - 32; // Capitalise first letter
             this->nodeCityName[0] = firstLetVal;
        }

        while(n <= MAX_SIZE - 1)
        {
            if((this->nodeCityName[n] >= 65) && (this->nodeCityName[n] <= 90))
            {
                letVal = this->nodeCityName[n] + 32;
                this->nodeCityName[n] = letVal;
            }
            n++;
        }
        //cityNameInput = this->nodeCityName;
    }

};



class Locations
{
private:
    int size;

public:

    Locations(){

    }; // constructor for the class

    locationNode* Head;

    //int Add(locationNode* Item);



};

And here is the file containing main:

// U08221.cpp : main project file.

#include "stdafx.h"
#include "Locations.h"
#include <iostream>
#include <string>
#include <fstream>

using namespace std;

int n = 0,x, locationCount = 0, MAX_SIZE = 35; 
string cityNameInput;
char targetCity[35];
bool acceptedInput = false, userInputReq = true, match = false, nodeExists = false;// note: addLocation(), set to true to enable user input as opposed to txt file

locationNode *start_ptr = NULL; // pointer to first entry in the list
locationNode     *temp, *temp2; // Part is a pointer to a new locationNode we can assign changing value followed by a call to Add
locationNode *seek, *bridge;

void setElementsNull(char cityParam[])
{
    int y=0, count =0;
    while(cityParam[y] != NULL)
    {
        y++;
    }

    while(y < MAX_SIZE)
    {
        cityParam[y] = NULL;
        y++;
    }
}
void addLocation()
{

    temp  = new locationNode; // declare the space for a pointer item and assign a temporary pointer to it

    if(!userInputReq) // bool that determines whether user input is required in adding the node to the list
    {
cout << endl << "Enter the name of the location: ";
cin >> temp->nodeCityName;
tem开发者_StackOverflowp->CorrectCase();
setElementsNull(temp->nodeCityName);
cout << endl << "Please enter the latitude value for this location: ";
cin >> temp->nodeLati;
cout << endl << "Please enter the longitude value for this location: ";
cin >> temp->nodeLongi;
cout << endl;
    }
temp->Next = NULL; //set to NULL as when one is added it is currently the last in the list and so can not point to the next


if(start_ptr == NULL){ // if list is currently empty, start_ptr will point to this node

    start_ptr = temp;
}

else
       { temp2 = start_ptr;
         // We know this is not NULL - list not empty!
         while (temp2->Next != NULL)
           {  
               temp2 = temp2->Next; // Move to next link in chain until reach end of list
           }

         temp2->Next = temp;
       }

++locationCount; // increment counter for number of records in list
if(!userInputReq){
cout << "Location sucessfully added to the database! There are " << locationCount << " location(s) stored" << endl;
}
}

void populateList(){


    ifstream inputFile;
    inputFile.open ("locations.txt", ios::in);
    userInputReq = true;
    temp  = new locationNode; // declare the space for a pointer item and assign a temporary pointer to it

 do
 {

      inputFile.get(temp->nodeCityName, 35, ' ');
      setElementsNull(temp->nodeCityName);
     inputFile >> temp->nodeLati;
    inputFile >> temp->nodeLongi;
    setElementsNull(temp->nodeCityName);


        if(temp->nodeCityName[0] == 10) //remove linefeed from input
        {
            for(int i = 0; temp->nodeCityName[i] != NULL; i++)
            {
                temp->nodeCityName[i] = temp->nodeCityName[i + 1];
            }
        }
     addLocation();
 }
  while(!inputFile.eof());


  userInputReq = false;
  cout << "Successful!" << endl << "List contains: " << locationCount << " entries" << endl; 
  cout << endl;

  inputFile.close();
  }

bool nodeExistTest(char targetCity[]) // see if entry is present in the database
{

    match = false;

    seek = start_ptr;

    int letters = 0, letters2 = 0, x = 0, y = 0;


    while(targetCity[y] != NULL)
    {
        letters2++;
        y++;
    }



while(x <= locationCount) // locationCount is number of entries currently in list
{
    y=0, letters = 0;
    while(seek->nodeCityName[y] != NULL) // count letters in the current name
    {
        letters++;
        y++;
    }


    if(letters == letters2) // same amount of letters in the name
    {
        y = 0;

            while(y <= letters) // compare each letter against one another
                {

                    if(targetCity[y] == seek->nodeCityName[y])
                        {
                            match = true;
                            y++;
                                }
                    else
                    {
                    match = false;
                    y = letters + 1; // no match, terminate comparison
                    }
                }


    }
    if(match)
    {

        x = locationCount + 1; //found match so terminate loop

    }

    else{
        if(seek->Next != NULL)
        {
        bridge = seek; 
        seek = seek->Next;
        x++;
        }
        else
        {
            x = locationCount + 1; // end of list so terminate loop
        }
    }

}
  return match;
}

void deleteRecord() // complete this
{
    int junction = 0;
    locationNode *place;
    cout << "Enter the name of the city you wish to remove" << endl;
    cin >> targetCity;
    setElementsNull(targetCity);

if(nodeExistTest(targetCity)) //if this node does exist
{
    if(seek == start_ptr) // if it is the first in the list
    {
        junction = 1;
   }

    if(seek != start_ptr && seek->Next == NULL) // if it is last in the list
    {
        junction = 2;
   }


switch(junction) // will alter list accordingly dependant on where the searched for link is
{
case 1:
    start_ptr = start_ptr->Next;
        delete seek;
        --locationCount;
            break;

case 2:

        place = seek;
        seek = bridge;
        delete place;
        --locationCount;
            break;

default:
    bridge->Next = seek->Next;
    delete seek;
    --locationCount;
    break;
}
}

else 
{   cout << targetCity << "That entry does not currently exist" << endl << endl << endl;
    }

}


void searchDatabase()
{
    char choice;
    cout << "Enter search term..." << endl;
    cin >> targetCity;

    if(nodeExistTest(targetCity))
    {
        cout << "Entry: " << endl << endl;
    }
    else
    {
        cout << "Sorry, that city is not currently present in the list." << endl << "Would you like to add this city now Y/N?" << endl;
        cin >> choice;

        /*while(choice != ('Y' || 'N'))
        {
            cout << "Please enter a valid choice..." << endl;
            cin >> choice;
        }*/

        switch(choice)
        {
        case 'Y':
            addLocation();
            break;

        case 'N':
            break;

        default :
            cout << "Invalid choice" << endl;
            break;
        }
    }
}



void printDatabase()
{
    temp = start_ptr; // set temp to the start of the list
do
  {  if (temp == NULL)
  {
       cout << "You have reached the end of the database" << endl;
  }
     else
       {  // Display details for what temp points to at that stage
          cout << "Location : " << temp->nodeCityName << endl;
          cout << "Latitude : " << temp->nodeLati << endl;
          cout << "Longitude : " << temp->nodeLongi << endl;
          cout << endl;

          // Move on to next locationNode if one exists
          temp = temp->Next;
       }
  }
while (temp != NULL);
}





void nameValidation(string name)
    {
        n = 0; // start from first letter
        x = name.size();

    while(!acceptedInput)
    {

        if((name[n] >= 65) &&  (name[n] <= 122)) // is in the range of letters
            {
                while(n <= x - 1)
                {
            while((name[n] >=91) && (name[n] <=97)) // ERROR!!
            {
            cout << "Please enter a valid city name" << endl;
            cin >> name;
            }
            n++;
                }
            }
        else {
            cout << "Please enter a valid city name" << endl;
            cin >> name;
        }

    if(n <= x - 1)
    {
        acceptedInput = true;
    }
    }
    cityNameInput = name;
    }






int main(array<System::String ^> ^args)
{
//main contains test calls to functions at present

    cout << "Populating list...";
    populateList();
    printDatabase();

    deleteRecord();
    printDatabase();
    cin >> cityNameInput;


}

The text file contains this (ignore the names, they are just for testing!!):

Lisbon 45 47
Fattah 45 47
Darius 42 49
Peter 45 27
Sarah 85 97
Michelle 45 47
John 25 67
Colin 35 87
Shiron 40 57
George 34 45
Sean 22 33

The output omits Lisbon, but adds on a garbage entry with nonsense values. Any ideas why? Thank you in advance.


The main function creates a new locationNode and stores it in the global variable temp, then reads the first dataset and stores it in that node.

Then you call addLocation() which starts by creating another new locationNode which replaces the existing one in temp. This new node is then inserted into the list.

The next iteration of the main loop then fills that temp value with values and addLocation() inserts another brand new locationNode into the list. So the first dataset isn't stored in the list and each iteration ends up by inserting an uninitialized new node.

As you see using global variables can lead to confusing situations and you code would surely become clearer if you were passing the nodes as parameters to your functions.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号