1

So, my code is supposed to read a file of movies, save the information to an array of structures, and from there we are supposed to execute several options from the user. Afterwards we have to save the information to a new file with the same name.

The options for the user are:

  1. to insert a movie
  2. to take a word and search for a movie with that word
  3. to provide a list of the movies and
  4. to exit.

So far, my program is working fine mostly. I do have a problem with the insert movie part. The description for the insert movie part is that you have to take in a name for a movie, check the whole array of structures and see if the exact same name is repeated, if not, to enter the movie and its information.

PROBLEMS

  1. For some reason, when I use gets, or fget or getline to take in a name of a movie, my program is not working. It does not let me enter a string and simply fills it out with a line (I think).

  2. Another problem I have is that if I use scanf (just to enter a movie which name is just one word), it works, and it updates the array perfectly. However, even though it updates the array of structure (which I notice because when I want to see a list of movies, the one I inserted shows up), if I try to insert another movie, my program is not using the last movie I inserted to compare to see if it exists.

I am providing my whole program because I do not know if those problems may be happening because some other function of mine is not working properly. The information of the text file is at the bottom, underneath the program. Each line is supposed to be year, genre, ratings, name.

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

struct movies {
    int year;
    int genre;
    float rating;
    char name[100];
};

int main(int argc, char *argv[]) {
int a,b,j,k,var,n,option1,f,linenum,i,u;
int pos[10];
struct movies E[200];
char text[50], option[20];
FILE *fp;

//checking to see if there is enough arguments
if (argc<2) {
    printf("Error: Some parameters missing.\n");
    return -1;
}

//Taking the name of the file
i = 0;
while(argv[1][i]!='\0') {
    text[i] = argv[1][i];
    i++;
}
text[i]='\0';

//Opening the file
fp=fopen(text,"r");
if(fp==NULL) {
    printf("Error opening file.\n");
    return -2;
}

//Taking the information from each line of the file
linenum=0;
char line[100];
while (fgets(line,sizeof(line),fp)!=NULL) {
    //if there are more than 200 movies break the loop.
    if(linenum==199) {
        printf("Maximum number of movies allowed is 200\n");
        break;
    }
    int m=sscanf(line,"%i,%i,%f\n", &E[linenum].year, &E[linenum].genre, &E[linenum].rating);
    //Extracting the name
    j=0;
    k=0;
    while(line[k]!='\0') {
        if(line[k]==',') {
            pos[j]=k;
            j++;
            k++;
        }
        k++;
    }
    var=pos[j-1]+1;
    n=0;
    while(line[var]!='\0') {
        E[linenum].name[n]=line[var];
        n++;
        var++;
    }
    E[linenum].name[n-1]='\0';
    linenum++;
}
fclose(fp);

//Executing the commands and interacting with the user
do {
    a=menu();
    scanf("%s",option);
    f=sscanf(option, "%i", &option1);
    if(f!= 1) {
        printf("The inserted value is not a number.\n");
        continue;
    }else {
        b=execute(option1,linenum,E,&linenum);
    }
}while(b!=-1);

//Writing the file
fp=fopen(text,"w");
if(fp==NULL) {
    printf("Error opening file.\n");
    return -2;
}
for(u=0;u<=linenum-1;u++) {
    fprintf(fp,"%i,%i,%.1f,%s\n",E[u].year,E[u].genre,E[u].rating,E[u].name);
}
fclose(fp);
printf("Good bye!!!\n");
return 0;
}


//Creating a menu
int menu() {
    printf("Choose from the options below:\n");
    printf("1.Insert a movie\n");
    printf("2.Search for movie and see its info\n");
    printf("3.List of movies\n");
    printf("4.Exit\n");
    return 0;
}

//Executing the choice of the user
int execute(int op,int linenum, struct movies *M,int *u) {
int a,b;
if(op==1) {
    a=InsertMovie(M,linenum,u);
    return 0;
}else if(op==2) {
    if(ReadMovie(M,linenum)==0) {
        return 0;
    }else {
        printf("There are no movies with that word. Sorry.\n");
    }
    return 0;
}else if(op==3) {
    b=ListMovies(M,linenum);
    return 0;
}else if(op==4) {
    return -1;
}else {
    printf("Not a valid option. Try again.\n");
    return 0;
}
return 0;
}


//Inserting a movie by the user
int InsertMovie(struct movies *M,int linenum,int *u) {
int f,w,x,y1,g1,n1,a;
float r1;
char n[100],y[5],g[2],r[4];
//Entering the name
printf("Insert name of the movie:");
scanf("%s",n);
for(a=0;a<=linenum;a++) {
    n1=existent(n,M,a);
    if(n1==-1) {
        printf("The movie already exists.\n");
        return -1;
    }else {
        //printf("%i\n",linenum);
        strcpy(M[linenum].name,n);
    }
}
do {
    //validating the input of the year and saving the info in the array of structures
    printf("Year of the movie: ");
    scanf("%s",y);
    f=sscanf(y, "%i", &y1);
    if(f!= 1) {
    printf("The inserted value is not a valid option.\n");
    }else {
        if(y1<1920 || y1>2016) {
            printf("Not a valid year.\n");
        }
    }
}while(f!=1 || y1<1920 || y1>2016);
M[linenum].year=y1;

do{
    //validating the input of the genre and saving it to the array of structures
    printf("Genre. For reference see option below:\n");
    printf("1.Fantasy\n");
    printf("2.Action\n");
    printf("3.Comedy\n");
    printf("4.Adventure\n");
    printf("5.Drama\n");
    printf("6.Other\n");
    scanf("%s",g);
    w=sscanf(g, "%i", &g1);
    if(w!= 1) {
        printf("The inserted value is not a valid option.\n");
    }else {
        if(g1<1 || g1>6) {
            printf("Not a valid genre.\n");
        }
    }
}while(w!=1 || g1<1 || g1>6);
M[linenum].genre=g1;

do {
    //validating the input of the ratings and saving it to the array of structures
    printf("What ratings has this movie (0->lowest,5->highest): ");
    scanf("%s",r);
    x=sscanf(r, "%f", &r1);
        if(x!= 1) {
            printf("The inserted value is not valid.\n");
        }else {
            if(r1<0.0 || r1>5.0) {
                printf("Not a valid rating.\n");
            }
        }
}while(x!=1 || r1<0.0 || r1>5.0);
M[linenum].rating=r1;
//updating the last line of the array
*u=linenum+1;
printf("Thanks!\n");
return 0;
}

//checking to see if a movie exists
int existent(char h[100],struct movies *E,int ind) {
int i,j,k,f,a;
char s[100], new1[100];
j=0;
k=0;
//copying the array to another local array so the original is not transformed
while(h[j]!='\0') {
s[k]=h[j];
k++;
h++;
}
s[k]='\0';
//Making it lower case to better comparison
for(i=0;i<100;i++) {
 if((s[i]>=97 && s[i]<=122) || (s[i]>=65 && s[i]<=90)) {
    if(s[i]>=65 && s[i]<=90) {
        s[i]=s[i]+32;
    }
 }
}
//Making lower case the names of the movies for better comparison
a=0;
f=0;
while(E[ind].name[f]!='\0') {
    if(E[ind].name[f]>=65 && E[ind].name[f]<=90) {
        new1[a]=E[ind].name[f]+32;
        a++;
    }else {
        new1[a]=E[ind].name[f];
        a++;
    }
    f++;
}
new1[a-1]='\0';
//Comparing the entered name with the names
if(strlen(s)==strlen(new1)) {
    if(strcmp(s,new1)==0) {
        return -1;
    }
}
return 0;
}

//List of movies
int ListMovies(struct movies *M,int l) {
int i;
printf("The movies are presented in this format: \n");
printf("Year,genre,ratings,name\n");
for(i=0;i<l;i++) {
    printf("%i,%i,%.2f,%s\n",M[i].year,M[i].genre,M[i].rating,M[i].name);
}
return 0;
}

//Getting the infromation of a specific movie
int ReadMovie(struct movies *M,int linenum) {
char n[100], titles[200][100],single[100],num[3];
int i,j,len,k,r, length[200];
int num1,h,f,u;
//Entering a word to find a movie
printf("Enter a word to find your movie: \n");
scanf("%s",n);
printf("This titles contain the word you entered:\n");
j=0;
for(i=0;i<linenum;i++) {
    //Passing the words to  the wordfinder function
    if(wordfinder(M,n,i)==0) {
        printf("%i.%s\n",j+1,M[i].name);
        len=(int)strlen(M[i].name);
        length[j]=len;
        u=j+1;
            for(k=0;k<=len;k++) {
                titles[j][k]=M[i].name[k];
            }
            j++;
        }
}

if(j==0) {
    return -1;
}

do {
//Validating the insertion of the number of the desired movie
printf("Enter the number of the movie you are looking for.Otherwise to exit the search press 0:\n");
scanf("%s",num);
f=sscanf(num, "%i", &num1);
if(f!= 1) {
    printf("The inserted character is not valid.\n");
} else if (num1==0) {
    //exit in case dont want to proceed
    return 0;
}else {
    if(num1<1 || num1>u) {
    printf("The number does not indicate a movie.\n");
}
}

}while(f!=1 || num1<1 || num1>u);
    for(r=0;r<=length[num1-1];r++) {
        single[r]=titles[num1-1][r];
    }
//Releasing the information of the desired movie
printf("This is the information for %s\n",single);
for(h=0;h<linenum;h++) {
    if(strcmp(single,M[h].name)==0) {
        printf("Year: %i\n",M[h].year);
        printf("Genre: %i\n",M[h].genre);
        printf("Ratings: %.2f\n",M[h].rating);
    }
}
return 0;
}

//Finding a word in a string
int wordfinder(struct movies *E,char str[100],int ind) {
char new1[100], new[100][100];
int k,i,j,l,w,r,q;

//Converting to lower case and saving the data to another array
for(k=0;k<100;k++) {
    if(E[ind].name[k]>=65 && E[ind].name[k]<=90) {
        new1[k]=E[ind].name[k]+32;
    }else {
        new1[k]=E[ind].name[k];
    }
}

//Converting to lower case the entered words
for(i=0;i<100;i++) {
    if((str[i]>=97 && str[i]<=122) || (str[i]>=65 && str[i]<=90)) {
        if(str[i]>=65 && str[i]<=90) {
            str[i]=str[i]+32;
        }
    }
}
//printf("%s\n",str);
//Saving the words of the titles to a two dimensional array
j=0;
l=0;
w=0;
while(new1[j]!='\0') {
    if(new1[j]>=97 && new1[j]<=122) {
        new[l][w]=new1[j];
        //printf("%c",new[l][w]);
        w++;
    }else {
        new[l][w]='\0';
        //printf("\n");
        l++;
        w=0;
    }
    j++;
}

//Comparing each individual word of the movie to the entered word
for(q=0;q<=l;q++) {
    r=compare(q,new,str);
    if(r==0) {
        return 0;
    }

}
    return -1;
}

//Comparing two strings
int compare(int row,char array[100][100],char word[100]) {
int f,h;
char cre[100];
f=0;
h=0;

//Creating an array with the word of the name of the movie
while(array[row][f]!='\0') {
    cre[h]=array[row][f];
    h++;
    f++;
}
cre[h]='\0';
//printf("%s\n",cre);
//if the words are equal then return 0, otherwise -1
if(strcmp(word,cre)==0) {
    memset(array,0,10000);
    return 0;
}
return -1;
}

Example input:

1939,1,3.9,The Wizard of Oz
1941,2,2.4,Citizen Kane
1972,5,3.3,The Godfather
1949,4,4.8,The Third Man
1964,1,1.1,A Hard Day's Night
1936,3,0.1,Modern Times
1950,5,1.5,All About Eve
1927,4,0,Metropolis
1920,1,2.7,Das Cabinet des Dr. Caligari. (The Cabinet of Dr. Caligari)
1944,4,4.3,Laura
1952,1,1.7,Singin' in the Rain
1938,5,2.5,The Adventures of Robin Hood
1965,2,1.2,Repulsion
1959,1,0.3,North by Northwest
1982,3,2.9,E.T. The Extra-Terrestrial
1933,4,3.8,King Kong
1950,1,2,Sunset Boulevard
1967,4,4.1,La Battaglia di Algeri
1954,3,1,Rear Window
1999,3,4.2,Toy Story 2
1941,3,3.9,The Maltese Falcon
1935,2,2.8,The Bride of Frankenstein
1974,5,3.4,The Godfather (Part II)
1951,4,0.9,Rashomon
2014,4,2.2,Boyhood
1934,5,3.6,It Happened One Night
1964,2,2.8,Dr. Strangelove Or How I Learned to Stop Worrying and Love the Bomb
1937,4,1.8,Snow White and the Seven Dwarfs
2010,4,4.3,Toy Story 3
1949,3,4.2,Ladri di Biciclette (The Bicycle Thief)
1948,2,4.9,The Treasure of the Sierra Madre
1954,4,1.5,Seven Samurai (Shichinin no Samurai)
1959,2,2.4,The 400 Blows (Les Quatre cents coups)
1940,1,4.2,The Philadelphia Story
1931,3,4.7,M
1954,2,0.4,On the Waterfront
2009,3,4.4,Up
1962,4,4.4,Lawrence of Arabia
1955,5,4.1,The Night of the Hunter
1979,4,1.8,Apocalypse Now
1958,4,4.5,Vertigo
1931,2,3.3,Frankenstein
1957,4,1.0,12 Angry Men (Twelve Angry Men)
1997,1,4,L.A. Confidential
1940,4,1.1,Rebecca
2008,2,4,The Wrestler
1951,3,1.2,A Streetcar Named Desire
1940,5,3.6,The Grapes of Wrath
2003,4,3.1,Finding Nemo
1948,1,4.3,The Red Shoes
1970,2,2.9,The Conformist
1940,3,0.6,Pinocchio
1935,1,2.3,The 39 Steps
1953,1,5,The Wages of Fear
1959,5,1.6,Anatomy of a Murder
1975,1,3.7,Jaws
1995,5,4.1,Toy Story
1974,3,2.3,Chinatown
1950,2,4.4,The Rules of the Game
1925,2,2,Battleship Potemkin
2008,1,4.8,Man on Wire
1971,4,3.7,The Last Picture Show
1963,5,3.8,The Leopard
1953,2,1.3,Roman Holiday
1976,2,2.2,Taxi Driver
1925,3,3.5,The Gold Rush
1956,1,4.5,The Searchers
1967,3,2.6,Cool Hand Luke
1977,3,1.7,Annie Hall
1968,4,1.4,Rosemary's Baby
2011,5,2.6,The Artist
1946,5,2.7,The Best Years of Our Lives
1957,3,2.1,Sweet Smell of Success
1964,1,4.9,Mary Poppins
2014,5,4.6,Life Itself
1951,5,1.9,Strangers on a Train
2008,5,4.5,Let the Right One In
2013,1,2.1,Before Midnight
1967,5,0.7,Playtime
2013,3,1.6,Short Term 12
1984,4,4.7,The Terminator
1969,1,3.8,The Wild Bunch
1931,5,2.5,City Lights
2013,2,0.2,Mud
1980,2,0.8,Raging Bull
1974,2,1.9,Badlands
1956,4,3.5,Invasion of the Body Snatchers
1971,3,3.2,The French Connection
1986,5,1.4,Aliens
1957,2,3.9,Kumonosu Jo (Throne of Blood)
1972,5,3.1,The Discreet Charm Of The Bourgeoisie
1980,1,1.3,Airplane!
1973,1,5,Mean Streets
1940,2,3.4,His Girl Friday
1962,5,4,The Manchurian Candidate
1968,5,0.5,Once Upon a Time in the West
1974,4,3,The Conversation
1962,3,3.0,Eyes Without a Face
1956,3,3.2,Forbidden Planet
1997,2,4.6,The Sweet Hereafter
saikumarm
  • 1,565
  • 1
  • 15
  • 30
dperez
  • 39
  • 3
  • Have you tried to come up with an MCVE? Have you tried to use a debugger? – n. m. could be an AI Dec 10 '14 at 16:38
  • I haven't checked your code,but I have a strong feeling that [clearing the input stream](http://stackoverflow.com/questions/7898215/how-to-clear-input-buffer-in-c) before the `fgets` which does not work will solve the first problem. – Spikatrix Dec 10 '14 at 16:39
  • I do not know what you mean by a debugger. I am kind of new to programming. I do write printf functions to see what is going on, and what I am missing an so on. Is that what you are referring to? – dperez Dec 10 '14 at 16:52
  • What do you mean by clearing the input stream? Clearing it after I read the file lines? – dperez Dec 10 '14 at 16:55
  • I just figured out what you said about clearing the stream and now that part works. Thank you very much. Any recommendation on what can I do to fix the other part? – dperez Dec 10 '14 at 17:04
  • Suggest changing major portion of `while()` to `if (4 != sscanf(line,"%i ,%i ,%f , %99[^\n]", &E[linenum].year, &E[linenum].genre, &E[linenum].rating, E[linenum].name)) break;` Note: although present code saves the return value of `sscanf()` in `m`, it does not test it. – chux - Reinstate Monica Dec 10 '14 at 17:26
  • Thanks for the comment. What I am really stuck with now is why is the program not updating the array of structures in such way that I can compare a newly entered name to a previous entered name by the user. – dperez Dec 10 '14 at 17:33

1 Answers1

0

scanf("%s",n); does not read a string with spaces (or any white-space) in it.

1) To read a movie title with spaces, use fgets()

printf("Insert name of the movie:");
// scanf("%s",n);

if (fgets(n, sizeof n, stdin) == NULL) Handle_EOF();
// remove trailing \n
size_t len = strlen(n);
if (len && n[len-1] == '\n') n[--len] = 0;

2) Replace all other user input with fgets().
Mixing scanf() with fgets() is problematic as scanf() often does not consume the final '\n' while fgets() does.

//scanf("%s",y);
if (fgets(y, sizeof y, stdin) == NULL) Handle_EOF();
f=sscanf(y, "%i", &y1);
chux - Reinstate Monica
  • 143,097
  • 13
  • 135
  • 256
  • Perfect. Thanks. Will do. What about the other problem? – dperez Dec 10 '14 at 18:10
  • I thought this may fix 1 & 2. Please specify "other problem". – chux - Reinstate Monica Dec 10 '14 at 18:12
  • SO, I insert the name of a movie and it works fine. Then I check that the movie was listed in the array of structures by pressing the option for list movies, and effectively the movie is there. Now, when I want to insert a movie, the program check that the movie's name does not exist in the array. What happens is that when I enter a second name, the program is not comparing the name that just been entered with the last name I enter. So, if I enter movie Lucy, for example, if I want to enter movie Lucy again, it should not let me do it (with perfect execution0 but it does. – dperez Dec 10 '14 at 19:51
  • In your revised code, check that the movie name entered and the movie names read from the file do not have extraneous leading or following white-space. Suggest printing their values as `printf("\"%s\"", name)` to see. – chux - Reinstate Monica Dec 11 '14 at 13:19