Function to sort singly linked list of airports by latitude. how would I pass in
ID: 3866039 • Letter: F
Question
Function to sort singly linked list of airports by latitude.
how would I pass in a struct into a function that manipulates a singly linked list and sorts it in order.
//singly linked list struct
typedef struct lListAirPdata{
airPdata *curAirPdata;
struct lListAirPdata *nextAirPdataList;
} lListAirPdata;
Using another function i have, i return latitude from the struct as a float and the numbers come out for example like this "29.1797" which can be used in this next function for lattitude sort.
full lattitude sort instructions below:
Explanation / Answer
main.c
-------------------------------------------
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "airPdata.h"
typedef struct lListAirPdata{
airPdata *curAirPdataP; //Pointer to the Airport Data
struct lListAirPdata *nextAirPdataList; // pointer to next
} lListAirPdata;
void parseLine(char *line, lListAirPdata **);
void printData(lListAirPdata *);
void exportData(lListAirPdata *);
void freeLinkedList(lListAirPdata *);
float sexag2decimal(char *degreeString);
void deleteStruct(airPdata *);
void sortByLocID(lListAirPdata *);
void sortByLatitude(lListAirPdata *);
#define BUFFER_SIZE 500
int main (int argc, char *argv[]){
// Declare input buffer and other parameters
FILE *fid;
char buffer[BUFFER_SIZE];
int count = 0;
int i;
char sortParam; /*sort parameter*/
// Declare a struct array and allocate memory.
lListAirPdata *airports = NULL;
// Check for command line input and open input file.
if(argc==3){
fid = fopen(argv[1], "r");
if(fid == NULL){
printf("%s ERROR: File %s not found. ", argv[0], argv[1]);
return 2;
}
sortParam = argv[2][0];
if (sortParam != 'a' && sortParam != 'A' && sortParam != 'n' && sortParam != 'N')
{
printf("%s ERROR: sortParameter invalid or not found. ", argv[0]);
// close the input file.
fclose(fid);
return 3;
}
}
else{
printf("%s ERROR: sortParameter invalid or not found. ", argv[0]);
return 1;
}
// Determine length of the file.
while(fgets(buffer, BUFFER_SIZE, fid) != NULL){
count++;
}
rewind(fid);
// Read and parse each line of the input file.
// ignore the airportser line
fgets(buffer, BUFFER_SIZE, fid);
for(i = 0; i < count - 1; i++){
fgets(buffer, BUFFER_SIZE, fid);
// fgets() includes the New Line delimiter in the output string.
// i.e. "This is my string. "
// We will truncate the string to drop the ' ' if it is there.
// Note: There will be no ' ' if the line is longer than the buffer.
if(buffer[strlen(buffer) - 1] == ' ') buffer[strlen(buffer)-1] = '';
parseLine(buffer, &airports);
}
// close the input file.
fclose(fid);
// Output the data to stdout.
//printData(count - 1, data);
//sort
sortByLocID(airports);
sortByLatitude(airports);
// Export to cvs file
exportData(airports);
// Free the memory used for fields of the structs.
freeLinkedList(airports);
return 0;
}
/*parse a line (record) and put info into apd*/
void parseLine(char *line, lListAirPdata **airports){
int i=0, j=0, commas=0;
char* temp;
lListAirPdata *newNode; //new node
lListAirPdata *current; //current node
airPdata *apd = (airPdata *)malloc(sizeof(airPdata));
if(apd==NULL){
printf("malloc failed to initialize airPdata. ");
exit(-1);
}
while(commas<15){
while(*(line+i)!=','){
i++;
}
// strncpy does not append a '' to the end of the copied sub-string, so we will
// replace the comma with ''.
*(line+i) = '';
switch (commas){
case 1: //Grab the second "field" - Location ID
apd->LocID = (char*)malloc(sizeof(char)*(i-j+1));
if(apd->LocID==NULL){
printf("malloc failed to initialize airPdata.LocID. ");
exit(-1);
}
strncpy(apd->LocID, line+j, i-j+1);
break;
case 2: //Grab the third "field" - Field Name
apd->fieldName = (char*)malloc(sizeof(char)*(i-j+1));
if(apd->fieldName==NULL){
printf("malloc failed to initialize airPdata.fieldName. ");
exit(-1);
}
strncpy(apd->fieldName, line+j, i-j+1);
break;
case 3: //Grab the fourth "field" - City
apd->city = (char*)malloc(sizeof(char)*(i-j+1));
if(apd->city==NULL){
printf("malloc failed to initialize airPdata.city. ");
exit(-1);
}
strncpy(apd->city, line+j, i-j+1);
break;
case 8: //Grab the ninth "field" - Latitude (sexagesimal string)
temp = (char*)malloc(sizeof(char)*(i-j+1));
if(temp == NULL){
printf("malloc failed to initialize airPdata.latitude. ");
exit(-1);
}
strncpy(temp, line+j, i-j+1);
apd->latitude = sexag2decimal(temp);
free(temp);
break;
case 9: //Grab the tenth "field" - Longitude (sexagesimal string)
temp = (char*)malloc(sizeof(char)*(i-j+1));
if(temp == NULL){
printf("malloc failed to initialize airPdata.longitude. ");
exit(-1);
}
strncpy(temp, line+j, i-j+1);
apd->longitude = sexag2decimal(temp);
free(temp);
break;
}
j=++i;
commas++;
}
//ignore Loc ID begin with numerical digits
//or FL or X followed by 2 digits
if (
(apd->LocID[0] >= '0' && apd->LocID[0] <= '9') ||
(strlen(apd->LocID) >= 4 && apd->LocID[0] == 'F' && apd->LocID[1] == 'L' &&
apd->LocID[2] >= '0' && apd->LocID[2] <= '9' && apd->LocID[3] >= '0' && apd->LocID[3] <= '9'
) ||
(strlen(apd->LocID) >= 3 && apd->LocID[0] == 'X' &&
apd->LocID[1] >= '0' && apd->LocID[1] <= '9' && apd->LocID[2] >= '0' && apd->LocID[2] <= '9'
)
)
{
deleteStruct(apd);
}else{
//create new node
newNode = (lListAirPdata *)malloc(sizeof(lListAirPdata));
if(newNode==NULL){
printf("malloc failed to initialize Node. ");
exit(-1);
}
newNode->curAirPdataP = apd;
newNode->nextAirPdataList = NULL;
//append to linked list
if (*airports == NULL)
{//add a head node
*airports = newNode;
}else{//add as tail node
current = *airports;
while (current->nextAirPdataList != NULL)
{
current = current->nextAirPdataList;
}
current->nextAirPdataList = newNode;
}
}
}
/*print data on console*/
void printData(lListAirPdata *airports){
int seqNumber = 1;
lListAirPdata *current = airports; //current node
printf("%-12s %-12s %-42s %-34s %-15s %-16s ", "seqNumber","Code", "Name", "City", "Latitude", "Longitude");
printf("%-12s%-12s %-42s %-34s %-15s %-16s ", "==========", "==========", "============", "====", "========", "=========");
while(current != NULL){
printf("%-12d%-12s %-42s %-34s %-11.4f %-12.4f ",seqNumber, current->curAirPdataP->LocID,current->curAirPdataP->fieldName,
current->curAirPdataP->city, current->curAirPdataP->latitude, current->curAirPdataP->longitude);
current = current->nextAirPdataList; //next node
seqNumber++;
}
}
/*
export in CSV format to OUTPUT_FILE_NAME
*/
void exportData(lListAirPdata *airports){
int seqNumber = 1;
lListAirPdata *current = airports; //current node
//print header line
printf("%s,%s,%s,%s,%s,%s ", "seqNumber", "code", "name", "city", "lat", "lon");
//print records
while(current != NULL){
printf("%d,%s,%s,%s,%.4f,%.4f ",seqNumber, current->curAirPdataP->LocID,current->curAirPdataP->fieldName,
current->curAirPdataP->city, current->curAirPdataP->latitude,current->curAirPdataP->longitude);
current = current->nextAirPdataList; //next node
seqNumber++;
}
}
/*free resources*/
void deleteStruct(airPdata *apd){
free(apd->city);
free(apd->fieldName);
free(apd->LocID);
}
float sexag2decimal(char *degreeString){
/*extract the content of degree string*/
int DD, MM, SS, MAS;
char D; /*direction*/
float decimalDegree; /*floating point representation of the calculated decimal degrees or 0.0*/
/*check null*/
if (degreeString == NULL){
return 0.0;
}
/*try to parse*/
if (sscanf(degreeString, "%d-%d-%d.%d%c", &DD, &MM, &SS, &MAS, &D) != 5){
return 0.0;
}
/*validate value*/
if (DD < 0 || DD > 180 || MM < 0 || MM > 59 || SS < 0 || SS > 59 ||
MAS < 0 || MAS > 9999 || (D != 'S' && D != 'N' && D != 'E' && D != 'W')){
return 0.0;
}
decimalDegree = (float)DD + (float)(MM / (float)60.0) + ((float)SS/(float)(60.0 * 60.0));
if (D == 'W' || D == 'S')
{
decimalDegree = -decimalDegree;
}
return decimalDegree;
}
//free linked list
void freeLinkedList(lListAirPdata *airports){
lListAirPdata *temp;
lListAirPdata *current; //current node
current = airports;
//iterate the linked list
while (current != NULL)
{
temp = current;
current = current->nextAirPdataList; //next node
deleteStruct(temp->curAirPdataP);
free(temp);
}
}
//Sorts the airports alphabetically by the string named Loc ID with only
//one airport per letter
void sortByLocID(lListAirPdata *airports){
lListAirPdata *current = airports;
lListAirPdata *next;
airPdata *data;
while (current != NULL)
{
next = current->nextAirPdataList;
while (next != NULL)
{
//compare and swap
if (current->curAirPdataP->LocID[0] > next->curAirPdataP->LocID[0])
{
data = current->curAirPdataP;
current->curAirPdataP = next->curAirPdataP;
next->curAirPdataP = data;
}
next = next->nextAirPdataList; //next node
}
current = current->nextAirPdataList; //next node
}
}
//sort by latitude
void sortByLatitude(lListAirPdata *airports){
lListAirPdata *current = airports;
lListAirPdata *next;
airPdata *data;
while (current != NULL)
{
next = current->nextAirPdataList;
while (next != NULL)
{
//compare and swap
if (current->curAirPdataP->latitude > next->curAirPdataP->latitude)
{
data = current->curAirPdataP;
current->curAirPdataP = next->curAirPdataP;
next->curAirPdataP = data;
}
next = next->nextAirPdataList; //next node
}
current = current->nextAirPdataList; //next node
}
}
-------------------------------------------------------
airPdata.h
--------------------------
#ifndef AIR_PDATA_H
#define AIR_PDATA_H
/*The structure struct airPdata*/
typedef struct airPdata{
char *siteNumber; /*FAA Site Number*/
char *LocID; /*Airports "Short Name", ie MCO*/
char *fieldName; /*Airport Name*/
char *city; /*Associated City*/
char *state; /*State*/
double latitude; /*atitude*/
double longitude; /*Longitude*/
char controlTower; /*Control Tower (Y/N)*/
} airPdata;
#endif
Related Questions
Navigate
Integrity-first tutoring: explanations and feedback only — we do not complete graded work. Learn more.