不能在.fgets,getline等不能正常工作中接受一串几个单词

时间:2014-12-10 16:24:13

标签: c

因此,我的代码应该读取电影文件,将信息保存到结构数组中,从那里我们应该从用户执行几个选项。 之后,我们必须将信息保存到具有相同名称的新文件中。

用户的选项是:

  1. 插入电影
  2. 用一个词来搜索带有该词的电影
  3. 提供电影列表和
  4. 退出。
  5. 到目前为止,我的程序工作正常。我确实有插入电影部分的问题。插入电影部分的描述是您必须为电影命名,检查整个结构数组,并查看是否重复完全相同的名称,如果没有,则输入电影及其信息。

    问题

    1. 出于某种原因,当我使用gets,或fget或getline来获取电影名称时,我的程序无效。它不允许我输入一个字符串,只是用一条线填充它(我认为)。

    2. 我遇到的另一个问题是,如果我使用scanf(只是输入一个名称只有一个单词的电影),它就可以工作,并且可以完美地更新数组。然而,即使它更新结构数组(我注意到,因为当我想看到电影列表,我插入的那个显示),如果我尝试插入另一部电影,我的程序不使用最后一部电影我插入比较以查看它是否存在。

    3. 我正在提供我的整个程序,因为我不知道这些问题是否可能发生,因为我的其他一些功能无法正常工作。文本文件的信息位于程序下方的底部。每行应该是年份,流派,评级,名称。

      #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
      

1 个答案:

答案 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);