user4833678
user4833678

Reputation:

Printing the array of structures

The addInfo() adds information into the array of structures and the function printList() outputs all of the elements of that array. But my printList() is outputting only the last element that was added. What can be wrong? Does it add elemets into the array incorrectly?

#include <stdio.h>
#include <stdlib.h>

//structure Location
typedef struct Location{
    char locName[35];
    char locDesc[85];
    float latitude;
    float longitude;
} LocationArray;

void addInfo(LocationArray **myArray, int*, int*);
void printList(LocationArray **myArray, int*);
void quitProgram();
void resizeArray(LocationArray **myArray, int*);

//Menu that receives the user input
//and performs corresponding operations based
//on the menu choice
void printMenu(LocationArray **myArray, int *count, int *max){
    printf("Hello! Please choose from the menu: \n");
    printf("Type 'A' or 'a' for adding additional location to the array\n");
    printf("Type 'P' or 'p' for printing the current list of locations\n");
    printf("Type 'Q' or 'q' to quit the program\n");

    char input = 0;
    scanf(" %c", &input);

    //Handles the invalid character input
    //exits if the character does not correspond
    //to the valid menu option
    while(input != 'A' && input != 'a'
        && input != 'P' && input != 'p'
        && input != 'Q' && input != 'q'){
            printf("Invalid character! Try entering a char again: \n");
            scanf(" %c", &input);
    }
    //Calls other functions
    //based on the character input
    switch(input){
    case 'A':
    case 'a':
        addInfo(myArray, count, max); //Calls function that adds more locations into the array
        break;
    case 'P':
    case 'p':
        printList(myArray, count); //Calls the function that prints the current list of locations
        break;
    case 'Q':
    case 'q':
        quitProgram(); //Calls the function that terminates the program
        break;
    }
}

//Adds info into the array of structures
void addInfo(LocationArray **myArray, int *count, int *numberOfLoc){

    if(*count == *numberOfLoc){ // Checks if the array is already full
        resizeArray(myArray, numberOfLoc); //Resizes the array if it's full

        printf("Please enter the name for the location:\n");
        scanf(" %[^\n]", &(*myArray)->locName); //Gets the user input for the Location Name
        printf("\nNow enter the description:\n");
        scanf(" %[^\n]", &(*myArray)->locDesc); //Gets the user input for the Location Description
        printf("\nNow enter the value for the latitude:\n");
        scanf("%f", &(*myArray)->latitude); //Gets the user input for the Latitude
        printf("\nNow enter the value for the longitude:\n");
        scanf("%f", &(*myArray)->longitude); //Gets the user input for the Latitude

        (*count)++; //Increment the count
    }
    else{ //Else, a used fills it out
        printf("Please enter the name for the location:\n");
        scanf(" %[^\n]", &(*myArray)->locName); //Gets the user input for the Location Name
        printf("\nNow enter the description:\n");
        scanf(" %[^\n]", &(*myArray)->locDesc); //Gets the user input for the Location Description
        printf("\nNow enter the value for the latitude:\n");
        scanf("%f", &(*myArray)->latitude); //Gets the user input for the Latitude
        printf("\nNow enter the value for the longitude:\n");
        scanf("%f", &(*myArray)->longitude); //Gets the user input for the Latitude

        (*count)++; //Increment the count
    }
}

//Resizes(doubles) the array size if the max limit is achieved
void resizeArray(LocationArray **myArray, int *numberOfLoc){
    *numberOfLoc = *numberOfLoc * 2; //Double the size

    LocationArray *temp;
    temp = (LocationArray*)realloc(*myArray, *numberOfLoc *sizeof(LocationArray)); //Reallocates more memory

    //Checks if the memory heap is exhausted
    if(temp == NULL){
        printf("The memory heap is exhausted!\n");
    }
    else{
        *myArray = temp; //Copy from the temp struct variable to myArray
    }
}

//Prints all of the elements of the array
void printList(LocationArray **myArray, int *count){
    if((*count) == 0){ //If the list is empty, then return
        printf("The list is empty!");
        return;
    }

    int i;
    for(i = 0; i < (*count); i++){
        printf("Location name: %s\n", (*myArray[i]).locName);
        printf("Description: %s\n", (*myArray[i]).locDesc);
        printf("Latitude: %f\n", (*myArray[i]).latitude);
        printf("Longitude: %f\n", (*myArray[i]).longitude);
    }
}

//Quits the program
void quitProgram(){
    printf("Bye!");
    exit(0);
}


int main()
{
    printf("How many locations would you like to be inside the array?\n");
    int numberOfLoc = 0; //variable for storing the size of the LocationArray
    scanf(" %d", &numberOfLoc); //gets the user input and stores in numerOfLoc

    LocationArray *myArray; //declares a LocationArray with the size of numberOfLoc
    myArray = (LocationArray*)malloc(numberOfLoc*sizeof(LocationArray));

    int count = 0;
    while(1){
        //Prints the menu
        printMenu(&myArray, &count, &numberOfLoc);
    }
    //Free the pointer
    free(myArray);
    return 0;
}

Upvotes: 2

Views: 111

Answers (1)

R Sahu
R Sahu

Reputation: 206717

In printList, you have the lines

for(i = 0; i < (*count); i++){
    printf("Location name: %s\n", (*myArray[i]).locName);
    printf("Description: %s\n", (*myArray[i]).locDesc);
    printf("Latitude: %f\n", (*myArray[i]).latitude);
    printf("Longitude: %f\n", (*myArray[i]).longitude);
}

Use of *myArray[i] is incorrect. That is equivalent to *(myArray[i]). You need to use: (*myArray)[i].

for(i = 0; i < (*count); i++){
    printf("Location name: %s\n", (*myArray)[i].locName);
    printf("Description: %s\n", (*myArray)[i].locDesc);
    printf("Latitude: %f\n", (*myArray)[i].latitude);
    printf("Longitude: %f\n", (*myArray)[i].longitude);
}

You can make code in printList simpler by changing the argument to LocationArray *myArray and int count.

void printList(LocationArray *myArray, int count){
    if(count == 0){ //If the list is empty, then return
        printf("The list is empty!");
        return;
    }

    int i;
    for(i = 0; i < count; i++){
        printf("Location name: %s\n", myArray[i].locName);
        printf("Description: %s\n", myArray[i].locDesc);
        printf("Latitude: %f\n", myArray[i].latitude);
        printf("Longitude: %f\n", myArray[i].longitude);
    }
}

and make sure to change the call to the function. Instead of

printList(myArray, count);

use

printList(*myArray, *count);

Further cleanup

scanf(" %[^\n]", &(*myArray)->locName);
scanf(" %[^\n]", &(*myArray)->locDesc);

are wrong on two accounts.

  1. You don't need to use &.
  2. You need to use the count-th element of myArray. The above always store the data in the first element of myArray.

use

scanf(" %[^\n]", (*myArray)[*count].locName);
scanf(" %[^\n]", (*myArray)[*count].locDesc);

Modify the other scanf lines also to:

scanf("%f", &(*myArray)[*count].latitude);
scanf("%f", &(*myArray)[*count].longitude);

Upvotes: 1

Related Questions