Home > Software design >  Array of structs in C, am I going through each index in my program? Can I make it Dynamic?
Array of structs in C, am I going through each index in my program? Can I make it Dynamic?

Time:07-30

My program works fine, but without the if(listsize == list) condition it will let me continue to add movies, and the display works fine as well and all movies will continue to be displayed. However, when ending the program I get a smash stack detected error. Can I make this array of struct dynamic so that I can keep adding an indefinite amount of movies? Also, I'm just now learning structs and this is my first program using them, in my array am I correctly indexing and storing data in movie1, movie2, and movie3? It works, but I feel like im doing a lot of things wrong here. Also, I tried to use fgets to get a line of text for the movie title and director, but it would ask for the data and then wouldn't pause for the data to be entered, and would skip to asking for the director name, and then when data was entered it would loop a lot of print statements

#include <stdio.h>
#include <string.h>
#define list 3

typedef struct{
  char title[25];
  char director[25];
  int release;
  int runtime;
} movieInfo;

void entermovie(movieInfo movie[], int i){
  printf("Enter the title of the movie: ");
  scanf(" %[^\n]s", movie[i].title);
  getchar();
  printf("Enter the director of the movie: ");
  scanf(" %[^\n]s", movie[i].director);
  getchar();
  printf("Enter the release date of the movie: ");
  scanf("%d", &movie[i].release);
  printf("Enter the movie runtime: ");
  scanf("%d", &movie[i].runtime);
    
}
void displaydata(movieInfo movie[], int listsize){
  for(int i = 0; i < listsize;i  ){
    printf("Movie %d data:\n"
      "Title:        %s\n"
      "Director:     %s\n"
      "Release date: %d\n"
      "Runtime:      %d\n", i   1, movie[i].title, movie[i].director, movie[i].release, movie[i].runtime);
  }
}

void askChoice(){
  printf("Enter 1 to add movie data\nEnter 2 to view the movie data stored\nEnter 3 to exit the program\n");
}

int main(void) {
  int listsize = 0;
  char choice;
  movieInfo movie1, movie2, movie3;
  
  movieInfo movies [list] = {movie1, movie2, movie3};

  while(choice != '3'){
    askChoice();
    scanf(" %c", &choice);
    switch(choice){
      case '1':
        if(listsize == list){
          printf("\nMaximum storage reached\n");
          break;
          }
        entermovie(movies, listsize);
        listsize  ;
        break;
      case '2':
        if(listsize == 0){
          printf("\n\nNo Movie data is currently stored\n\n");
          break;
        }
        displaydata(movies, listsize);
        break;
      case '3':
        break;
      default:
        printf("Please enter a valid choice\n");
        break;
      }
      

  }
  printf("Exiting the program, goodbye");

  
  return 0;
}

CodePudding user response:

Start with an empty list:

int listsize = 0;
movieInfo *movies = NULL;

Use only realloc() to grow your list:

case '1':
    movieInfo *tmp = realloc( movies, (listsize   1) * sizeof(movieInfo) );
    if( tmp == NULL )
        printf( "Error: Cannot expand list\n" );
    else {
        movies = tmp;
        entermovie( movies, listsize ); // listsize no longer out-of-bounds
        listsize  ;
    }
    break;

realloc() will return NULL if unsuccessful.

The rest of your code does not need to be changed because of C's equivalence between pointers and arrays.

Consider improving the flow of option '2'. One wants to write clear, concise code.

case '2':
    if( listsize )
        displaydata( movies, listsize );
    else
        printf( "No Movies currently stored\n" );
    break;

Maybe move that test and message into displaydata() to make the higher level function 'cleaner'.

And, when the list is no longer needed:

if( movies )
    free( movies );
  • Related