因此,我的代码应该读取电影文件,将信息保存到结构数组中,从那里我们应该从用户执行几个选项。 之后,我们必须将信息保存到具有相同名称的新文件中。
用户的选项是:
到目前为止,我的程序工作正常。我确实有插入电影部分的问题。插入电影部分的描述是您必须为电影命名,检查整个结构数组,并查看是否重复完全相同的名称,如果没有,则输入电影及其信息。
问题
出于某种原因,当我使用gets,或fget或getline来获取电影名称时,我的程序无效。它不允许我输入一个字符串,只是用一条线填充它(我认为)。
我遇到的另一个问题是,如果我使用scanf(只是输入一个名称只有一个单词的电影),它就可以工作,并且可以完美地更新数组。然而,即使它更新结构数组(我注意到,因为当我想看到电影列表,我插入的那个显示),如果我尝试插入另一部电影,我的程序不使用最后一部电影我插入比较以查看它是否存在。
我正在提供我的整个程序,因为我不知道这些问题是否可能发生,因为我的其他一些功能无法正常工作。文本文件的信息位于程序下方的底部。每行应该是年份,流派,评级,名称。
#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;
}
示例输入:
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
答案 0 :(得分:0)
scanf("%s",n);
不会读取包含空格(或任何空格)的字符串。
1)要使用空格阅读电影标题,请使用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)用fgets()
替换所有其他用户输入。
将scanf()
与fgets()
混合是有问题的,因为scanf()
通常不会消耗'\n'
fgets()
。{/ p>
//scanf("%s",y);
if (fgets(y, sizeof y, stdin) == NULL) Handle_EOF();
f=sscanf(y, "%i", &y1);