hi
how do I put words into a specified location of a 2d array using scanf?

string movies[100][6]={};
in main

i need at least 100 rows and 5 columns

i want the user to enter the movie id, name
year, type and availability
it will be stored in a 2d array
i want to list what I've entered after words

it compiles but freezes when i try to list..
and if i hard coded the data it will list with no problems

i don't have any experience in strings..please help

here is my code..the part of adding a movie:

void Add_Movie(string movies[100][6]){
        int answer;
        int i;

        for(i=0;i<100;i++){

            printf("Movie ID:");
            scanf("%s", &movies[i][0]);

            printf("Movie Title:");
            scanf("%s", &movies[i][1]);

            printf("Movie Year:");
            scanf("%s", &movies[i][2]);

            printf("Movie Type:");
            scanf("%s", &movies[i][3]);

            printf("Availability:");
            scanf("%s", &movies[i][4]);

    printf("\n Do you want to add another movie? if no, enter 0");
    scanf("%i",&answer);
    if(answer == 0)
    break;
    }
           List_Movie(movies);

    }

here is the listing part:

void List_Movie(string movies[100][6]){

        int i,j=1;
        printf(" \n 4.List Movies\n");
        printf("\n      #   Movie ID\t  Title\t      Year\t Type\t Available\n");
        printf("     --------------------------------------------------------------\n");
        for(i=0;i<10;i++){
            if (movies[i][0]==NULL)
            break;

            if (movies[i][4]!="no"){


        printf("%7i  %6s  %17s  %6s  %9s  %9s\n", j , movies[i][0], movies[i][1], movies[i][2], movies[i][3], movies[i][4] );
            j++;
            }
        }

    }

what am i doing wrong??

@jonsca
i used string in C as a pre-defined type name
i wrote a typedef statement that defines string as a synonym
for the character pointer expression
typedef char* string;

its in the tools library

is there another way other than string??

Edited 6 Years Ago by deeer: n/a

here it is..its incomplete but executable..do you need the tools file?

#include "tools.c"

void Add_Movie(string movies [][]);
void Delete_Movie(string movies[][]);
void Modify_Movie();
void List_Movie(string movies[][]);
void Add_Customer();
void Delete_Customer();
void Modify_Cusyomer();
void List_Customer();
void Exit();



main(){
string movies[100][6]={{"212","Titanic","1997","Drama","yes"},
                       {"114","The Godfather","1972","mafia","yes"},
                       {"439","The Matrix","1998","SciFi","no"},
                       {"821","Avatar","2009","SciFi","yes"}};

        /*banner();*/

 int n;
    printf("\t\t **** Main menu ****\n\n");
    printf("\t1.Add Movie.\t5.Add Customer.\n\t2.Delete Movie.\t6.Delete Customer.\n");
    printf("\t3.Modify Movie.\t7.Modify Customer.\n\t4.List Movie.\t8.List Customer.\n");
    printf("\n\n \t\t\t\t0.Exit \n");
    scanf("%i",&n);
    switch(n){
        case 0:printf("\n Good Bye\n");
        break;
        case 1:Add_Movie(movies);
        break;
        case 2:Delete_Movie(movies);
        break;
        case 3:Modify_Movie();
        break;
        case 4:List_Movie(movies);
        break;
        case 5:Add_Customer();
        break;
        case 6:Delete_Customer();
        break;
        case 7:Modify_Cusyomer();
        break;
        case 8:List_Customer();
        break;
        default:printf(" Wrong number\n");
    }
}





    void Add_Movie(string movies[100][6]){
        int answer;
        int i;

        for(i=4;i<100;i++){

            printf("Movie ID:");
            scanf("%s", &movies[i][0]);

            printf("Movie Title:");
            scanf("%s", &movies[i][1]);

            printf("Movie Year:");
            scanf("%s", &movies[i][2]);

            printf("Movie Type:");
            scanf("%s", &movies[i][3]);

            printf("Availability:");
            scanf("%s", &movies[i][4]);

    printf("\n Do you want to add another movie? if no, enter 0");
    scanf("%i",&answer);
    if(answer == 0)
    break;
    }
           List_Movie(movies);

    }





      void Delete_Movie(string movies[100][6]){
               int i;
               string x;
               char sure;


          printf("Enter Movie ID to delete:");
          scanf("%s",&x);
          /*printf("Are You Sure you want to delete this movie? Y/N");
          scanf("%c%*c",&sure);*/
          /*while ( sure == 'N' || sure == 'n'){
              printf("Enter Movie ID to delete:");
              scanf("%i",&x);}*/

          for(i=0;i<=10;i++) {

              if (movies[i][0]==x){
              movies[i][4]="no";
              break;}
          }
        List_Movie(movies);
    }








     void Modify_Movie(){
        printf("\n coming soon");
        Exit();
    }







    void List_Movie(string movies[100][6]){

        int i,j=1;
        printf(" \n 4.List Movies\n");
        printf("\n      #   Movie ID\t  Title\t      Year\t Type\t Available\n");
        printf("     --------------------------------------------------------------\n");
        for(i=0;i<10;i++){
            if (movies[i][0]==NULL)
            break;

            if (movies[i][4]!="no"){


        printf("%7i  %6s  %17s  %6s  %9s  %9s\n", j , movies[i][0], movies[i][1], movies[i][2], movies[i][3], movies[i][4] );
            j++;
            }
        }
        Exit();

    }








    void Add_Customer(){
        printf(" \n coming soon");
        Exit();
    }



    void Delete_Customer(){
        printf("\n coming soon");
        Exit();
    }



    void Modify_Cusyomer(){
        printf("\n coming soon");
        Exit();
    }



    void List_Customer(){
        printf("\n coming soon");
        Exit();
    }








    void Exit() {
     int x;
     printf("\n\n9.back to main menu        0.Exit\n");
     scanf("%i",&x);

     switch (x) {
      case 0: printf("\tgood bye"); break;
      case 9: main(); break;
      default:printf(" Wrong number\n");
     }
    }

Sure, I mean I could probably recreate it (since it's just your includes and a typedef or two) but it'll be faster.

Your movies array may not be what you expect. If you have
char *moves[100][5];

Although you've neatly typedef'd it to look different, what you have is a char pointer array that is 100 x 5, and not a char array 100 x 5.

All you need is a flat file database.

Why not put the movie characteristics that you want to record, into a record, with fields? In C you'd use a

typedef struct {
  long id;
  char name[40]; //  (or char *name; and malloc the memory later)
  char lead_man [25];
  char lead_lady[25];
  char cat[25]; //category
  char direct[25]; //director
  char *notes; //malloc memory later)
}movie;

movie movies[100];  //make array of 100 records

Anyway, I'd recommend doing something like that. It groups all your data on a film, all together, and it's pretty simple to code one up.

I agree with Adak's suggestion. Part of the problem is that you are trying to write a string of unknown length to an (uninitialized) char array. Rather than having to "malloc" your way through you could make your array 3 dimensions (of char not char *) and would allow you a fixed amount of room in which to write characters (again the typedef makes things a bit confusing here for you as the programmer).
Either way, you should consider using fgets to read your strings in. An additional perk with doing that is being able to input titles, etc. with spaces in them.
One last thing is, don't call main() like you did on line 199. Let the other functions finish up and return rather than calling Exit().

Edited 6 Years Ago by jonsca: n/a

@Adak @jonsca
thank you for the replies

i changed it as you suggested
it worked ! i can now add data to the array and print them..

but I'm having problems with spaces when printing the list.
in add movie, when i try to enter a movie name with spaces
it will jump to the last scanf then print the other half in the next string

if the movie without spaces it will print ok but i cant put spaces between results when printing

for example sample prompt:
movie id:232
movie title:toy story
movie year:movie type: movie availability: yes

the output:
id title year type availability
232 toy 0 story yes

i think it has to do with pointers and memory location
but i don't know exactly what to change to make it work

other question: how do I return to main from the functions?
I mean , i want to finish my work (adding, modifying,deleting,listing)
then return the value to main and go there and when i want to list
the movies I want to see the latest modifications.


here is the full modified code:

#include "tools.c"
typedef struct{
     int id;
     char title[20];
     int year;
     char type[20];
     char availaibility[5];
 }movie;


/* Functions Prototype */
void Add_Movie(movie Videos[]);            /* this function is for adding Videos,it has one parameter which is an array called Videos and it stores Videos in it  */
void Delete_Movie(movie Videos[]);          /* this functoin is for deleting a specific movie from the array "Videos" */
void Modify_Movie(movie Videos[]);                         /*this function for edit any information in the array"Videos" */
void List_Movie(movie Videos[]);            /* this function is to review the Videos in the array */



main(){

     movie Videos[100]={{212,"Titanic",1997,"Drama","yes"},
                       {114,"The Godfather",1972,"mafia","yes"},
                       {439,"The Matrix",1998,"SciFi","no"},
                       {821,"Avatar",2009,"SciFi","yes"}};

     
        banner();

    int n;
    printf("\t\t **** Main menu ****\n\n");                           /* the list that appears when running the program */
    printf("\t1.Add Movie.\t5.Add Customer.\n\t2.Delete Movie.\t6.Delete Customer.\n");
    printf("\t3.Modify Movie.\t7.Modify Customer.\n\t4.List Movie.\t8.List Customer.\n");
    printf("\n\n \t\t\t\t0.Exit \n");

    scanf("%i",&n);                                                /* the user enters the suitable number base on what he needs*/
    switch(n){
        case 0:printf("\n Good Bye\n");                            /* 0 for exit */
        break;
        case 1:Add_Movie(Videos);                                  /* 1 to call the Add_Movie function for adding purposes*/
        break;
        case 2:Delete_Movie(Videos);                               /* 2 to call the Delete_Movie function to delete any Videos */
        break;
        case 3:Modify_Movie(Videos);                                     /* 3 to call the Modify_Movie function for editing*/
        break;
        case 4:List_Movie(Videos);                                 /* 4 to call the List_Movie function that shows the Videos' list */
        break;
        default:printf(" Wrong number\n");                        /* if the user enters a wrong number which is out of the list, the program shows this MSG */
    }
}





    void Add_Movie(movie Videos[100]){                         /* this function is for adding Videos,it asks the user to prompt the movie's ID,tile,year,type and avalibility */
        int answer;
        int i,id,year;

        for(i=4;i<100;i++){

            printf("Movie ID:");
            scanf("%i", &Videos[i].id);

            printf("Movie Title:");
            scanf("%s", &Videos[i].title);

            printf("Movie Year:");
            scanf("%i", &Videos[i].year);

            printf("Movie Type:");
            scanf("%s", &Videos[i].type);

            printf("Availability:");
            scanf("%s", &Videos[i].availaibility);

    printf("\n Do you want to add another movie? if no, enter 0");    /* the function gives the user the choice to continue adding another movie or leaving..0 to exit */
    scanf("%i",&answer);
    if(answer == 0)
    break;
    }
           List_Movie(Videos);                                      /* to call the List_Movie function in order to show the Videos' list after adding*/

    }





      void Delete_Movie(movie Videos[100]){                   /* this function is to delete any movie,it asks the user to prompt the movie's ID and it searches for it
                                                                     then sets up the Availability's field with no in order to hide it */
               int i;
               int x;
               char sure;


          printf("Enter Movie ID to delete:");                    /* asking the user to prompt the ID for the movie he wants to delete */
          scanf("%i",&x);
          /*printf("Are You Sure you want to delete this movie? Y/N");
          scanf("%c%*c",&sure);
          while ( sure == 'N' || sure == 'n'){
              printf("Enter Movie ID to delete:");
              scanf("%i",&x);}*/

          for(i=0;i<=10;i++) {

              if (Videos[i].id==x){
                  strcpy(Videos[i].availaibility, "no"); /*searching for the movie that the user requires*/
              break;}
              if (Videos[i].id!=x){
               printf("no movie with that ID");break;}
          }
        List_Movie(Videos);                                        /* to call the List_Movie function in order to shoe the Videos' list after deleting */
    }








     void Modify_Movie(movie Videos[100]){                                        /* this function to edit any information */
        int z,i,j;
        List_Movie(Videos);                                        /* to call the List_Movie function in order to shoe the Videos' list after deleting */

        printf("\nEnter Movie ID to Modify:");                    /* asking the user to prompt the ID for the movie he wants to delete */
          scanf("%i",&z);

        for(i=0;i<=10;i++) {
            if (Videos[i].id==z)

             printf("\n  %i  %s  %i  %s \n", Videos[i].id,Videos[i].title, Videos[i].year, Videos[i].type );

         printf("\nchoose\n");
         printf("\n\t1.Edit Title  2.Edit Year   3.Edit Type\n");
         printf("\t0. Exit\n");
         scanf("%i",&j);
         switch (j) {
             case 0: break;
             case 1: printf("Enter New Title:");
                     scanf("%s",&Videos[i].title);
                     List_Movie(Videos);break;
             case 2: printf("Enter New year:");
                     scanf("%i",&Videos[i].year);
                     List_Movie(Videos); break;
             case 3: printf("Enter New type:");
                     scanf("%s",&Videos[i].type);
                     List_Movie(Videos); break;
         }

          break;
            }
    }







    void List_Movie(movie Videos[100]){                     /* this function is to review the Videos in the array "Videos" */

        int i,j=1,diff;
        printf(" \n 4.List Videos\n");
        printf("\n      #   Movie ID\t  Title\t      Year\t Type\t Available\n");
        printf("     --------------------------------------------------------------\n");
        for(i=0;i<10;i++){
            if (Videos[i].id==NULL)
            break;

           diff = strcmp(Videos[i].availaibility,"no");
           if (diff !=0) {                                         /*it checks up the availibilty feild for all Videos,if the
                                                                    availability field for any movie is "no", the function doesn't show it. */

        printf("%7i  %i  %s  %i  %s  %s\n", j , Videos[i].id,Videos[i].title, Videos[i].year, Videos[i].type, Videos[i].availaibility );
            j++;
            }
        }
                                                       /* to call the exit function to leave or to return to main*/
    }

Edited 6 Years Ago by deeer: n/a

i think it has to do with pointers and memory location
but i don't know exactly what to change to make it work

It actually has to do with the fact that scanf uses a space as an input delimiter (so once it hits a space it stops) and the rest of what you typed stays in the input stream and gets collected by the next scanf.
fgets works very nicely to get a full line of input.
Use the syntax fgets(Videos[i].title,sizeof(Videos[i].title),stdin); . The function will put a '\0' at the end for you so that will only leave you with 19 characters to play with. fgets will take in the '\n' at the end of a line so you can step through the string and replace '\n' with a '\0'

other question: how do I return to main from the functions?
I mean , i want to finish my work (adding, modifying,deleting,listing)
then return the value to main and go there and when i want to list
the movies I want to see the latest modifications.

Wrap from lines 28 to 48 in a do/while loop while n !=0. This way when your functions return to main() it'll be primed for another time through the menu. When the flow of the program reaches the end of a void function the flow returns to the calling function (same as it would if your function returned a value and the flow hit a return statement).
So if your user selects option 2, the delete movie function will be called and will execute until it gets to List_movie, at which point that function will execute to the end. Then control is returned back to Delete_movie which reaches the end and returns to main(). It's at that point that you want to trap the flow and return to the top with the do/while.

Edited 6 Years Ago by jonsca: n/a

@jonsca

thanks..
but how and where would I put it
i tried putting

fgets(Videos[i].title,sizeof(Videos[i].title),stdin);

instead of scanf but it skipped it
can you rewrite the correct whole format?

other thing, the hard coded data that i put in the array
how can i print them , just as a string %s?

It actually has to do with the fact that scanf uses a space as an input delimiter (so once it hits a space it stops) and the rest of what you typed stays in the input stream and gets collected by the next scanf.
fgets works very nicely to get a full line of input.
Use the syntax fgets(Videos[i].title,sizeof(Videos[i].title),stdin); . The function will put a '\0' at the end for you so that will only leave you with 19 characters to play with. fgets will take in the '\n' at the end of a line so you can step through the string and replace '\n' with a '\0'

Edited 6 Years Ago by deeer: n/a

That fgets() line of code you tried, was correct.

Whenever you use scanf() family of functions, you have to know how it works. Especially, when it will leave a newline char behind it, still on the keyboard buffer.

Numbers and char's ALWAYS leave a newline behind. It won't bother other scanf()'s for numbers, but it will bother char's (all the time, even one), and strings (if there are two or three of them).

I added getchar()'s after all the scanf()'s in your Add_movie() function, except the strings, and increased the size of the title. "The Hunt for Red October", wouldn't fit as is. ;) Then Add_movie() worked fine.

The getchar()'s don't stop the program, since they are matched up with the newlines present in the keyboard buffer. If you add too many getchar()'s, then it will stop the program, but just the right number, will not stop it, it just pulls the newlines off the keyboard buffer.

After you have the fgets() title into your struct array, you will want to remove the newline that was stored with it. This line of code will do that:

Videos[i]title[strlen(Videos[i].title) - 1] = '\0';

Without the above, the title will print out fine, but the rest of the display, will be down one row, because it still has the newline in it.

Edited 6 Years Ago by Adak: n/a

I tried putting the code like this

printf("\nMovie Title:");
            fgets(Videos[i].title,sizeof(Videos[i].title),stdin);
            Videos[i].title[strlen(Videos[i].title) - 1] = '\0';

didnt prompt me to enter..it skipped it ..why?

That fgets() line of code you tried, was correct.

Whenever you use scanf() family of functions, you have to know how it works. Especially, when it will leave a newline char behind it, still on the keyboard buffer.

Numbers and char's ALWAYS leave a newline behind. It won't bother other scanf()'s for numbers, but it will bother char's (all the time, even one), and strings (if there are two or three of them).

I added getchar()'s after all the scanf()'s in your Add_movie() function, except the strings, and increased the size of the title. "The Hunt for Red October", wouldn't fit as is. ;) Then Add_movie() worked fine.

The getchar()'s don't stop the program, since they are matched up with the newlines present in the keyboard buffer. If you add too many getchar()'s, then it will stop the program, but just the right number, will not stop it, it just pulls the newlines off the keyboard buffer.

After you have the fgets() title into your struct array, you will want to remove the newline that was stored with it. This line of code will do that:

Videos[i]title[strlen(Videos[i].title) - 1] = '\0';

Without the above, the title will print out fine, but the rest of the display, will be down one row, because it still has the newline in it.

I tried putting the code like this

printf("\nMovie Title:");
            fgets(Videos[i].title,sizeof(Videos[i].title),stdin);
            Videos[i].title[strlen(Videos[i].title) - 1] = '\0';

didnt prompt me to enter..it skipped it ..why?

This works, you aren't showing enough of your code for me to tell what's up with it.

void Add_Movie(movie Videos[100]){                         /* this function is for adding Videos,it asks the user to prompt the movie's ID,tile,year,type and avalibility */
  int answer, i,id,year;

  for(i=4;i<100;i++){
    printf("Movie ID:");
    scanf("%i", &Videos[i].id);
    getchar();
    printf("Movie Title:");
    fgets(Videos[i].title, sizeof(Videos[i].title), stdin);
    Videos[i].title[strlen(Videos[i].title) -1] = '\0';
        
    printf("Movie Year:");
    scanf("%i", &Videos[i].year);
    getchar();
    printf("Movie Type:");
    fgets(Videos[i].type, sizeof(Videos[i].type), stdin);
    Videos[i].type[strlen(Videos[i].type) -1] = '\0';
    
    printf("Availability:");
    scanf("%s", Videos[i].availaibility);

    printf("\n Do you want to add another movie? if no, enter 0: ");    /* the function gives the user the choice to continue adding another movie or leaving..0 to exit */
    scanf("%i",&answer);
    getchar();
    if(answer == 0)
      break;
  }
    List_Movie(Videos);                                      /* to call the List_Movie function in order to show the Videos' list after adding*/
}

Note that I did increase the length of title because it wouldn't handle longer strings, there.

yesss...finaaaly, it wooorked perfectly
thank you very much for your help Adak and jonsca
much appreciated :)

This question has already been answered. Start a new discussion instead.