0

ここで何が間違っているのかわかりません。ファイルからデータを正常に読み込むプログラムがあります。これを行うと、で読み取られたデータを検索/表示/削除できるようにする必要がありますが、これは行いません。printf()ファイルを読み取る関数にを追加すると、正しいデータが出力されるため、ファイルが正常に読み取られていることがわかります。ヘルプは素晴らしいでしょう。これがコードの簡略版です。

typedef struct friends_contact{

  char *First_Name;
  char *Last_Name;
  char *home;
  char *cell;
}fr;


int main() 
{
  fr friends[5];
  char buffer[BUFFSIZE];
  int counter=0;
  int i=0;

  menu(friends, &counter,i,buffer);

  getch();
  return 0;
}
//Menu function
void menu(fr*friends,int* counter, int i,char buffer[]) 
{
 int user_entry=0;
 int user_entry1=0;
 int user_entry2=0;
 char user_entry3[50]={'\0'};
 FILE *read;
 printf("Welcome! Would you like to import a file? (1)Yes or (2) No");
 scanf("%d",&user_entry1);
 if(user_entry1==1)
   {
    printf("Please enter a file name");
    scanf("%s",user_entry3); 
    read=fopen(user_entry3,"r");
   }else;

 do{
  int result;

  printf("\nPhone Book Application\n");
  printf("1) Add friend\n2) Delete friend\n3) Show a friend\n4) Show  phonebook\n5)Exit\n");   
  scanf("%d", &user_entry);
if(user_entry==1)
  {
    add_contact(friends,counter,i,buffer);
  }
if(user_entry==2)
  {
    delete_contact(friends ,counter,i);
  } 
if(user_entry==3)
  {
    result=show_contact(friends ,counter,i);
    if(result==0){
                  printf("\nName not Found\n");
                  }else{
                        result;
                        }

 }                  
if(user_entry==4)
 {
   print_contact(friends, counter,i,user_entry3);
   if(user_entry1==1)
     {
   file2(friends ,counter,i,buffer,read);
      }else;
 } 

}while(user_entry!=5);


 }

削除機能

//This is used to delete a name out of the book
char delete_contact(fr*friends ,int* counter, int i)
{
   char name_search[50]={'\0'};
   char Delete[5]={'\0'};

   printf("Search by last name\n");
   scanf("%s",name_search);//Name entry
   for(i=0;i<*counter;i++)
      {
       if(strcmp(name_search,friends[i].Last_Name)==0)//Copys over the name entered
         {                                       
          strcpy(friends[i].Last_Name,Delete);
         }
       }
    //Freeing up memory.
    free(friends[i].First_Name);
    free(friends[i].Last_Name);
    free(friends[i].home);
    free(friends[i].cell);   

    printf("\nName(s) has been deleted\n");             
}

印刷機能:

//This function prints out all the contact information
void print_contact(fr*friends ,int* counter, int i,char user_entry3[50]) 
{
    for( i = 0; i < *counter; i++)
    if (strlen(friends[i].First_Name) && strlen(friends[i].Last_Name)&&        strlen(friends[i].home)&& strlen(friends[i].cell ))
       {

          getFirst(friends, i);
          getLast(friends, i);
          getHome(friends, i);
          getCell(friends, i);
        }
}
//Displays the contact in which you are searching for.
int show_contact(fr*friends ,int* counter, int i) 
{  
   char name_search2[50]={'\0'};
   int flag=0;
   printf("Please enter a last name\n");
   scanf("%s",name_search2);
   for(i=0;i<*counter;i++)
      {
      //If the name is found, it reaturns the contact info.Now works for duplicate last names.
        if(strcmp(name_search2,friends[i].Last_Name)==0)
          {
             (strlen(friends[i].First_Name) && strlen(friends[i].Last_Name)&& strlen(friends[i].home)&& strlen(friends[i].cell ));

            getFirst(friends, i);
            getLast(friends, i);
            getHome(friends, i);
            getCell(friends, i);
            flag++;
          }
     }         


    return flag;
}    

読み込み機能:

void file2(fr*friends ,int* counter, int i,char buffer[],FILE*read)
{
  fseek(read, 0, SEEK_SET); 

  while (fscanf(read,"%s", buffer) != EOF) 
     {
       friends[*counter].Last_Name=malloc(BUFFSIZE*strlen(buffer));

       strcpy(friends[*counter].Last_Name, buffer);

       printf("%s\n",friends[*counter].Last_Name);

      }

}
4

1 に答える 1

0

読み取り関数を、配列のサイズを渡すこのようなものに変更してみてください。これにより、friends読み取りが多すぎてプログラムがクラッシュすることはありません。これは、テキスト ファイルから 1 行ずつ読み取っていることを前提としています。

これは、各構造体にアクセスしているときに範囲外にならないようcounterに、配列内の要素数より少ない間はループします。または、ファイルの終わりに達した場合は停止します。friends

メモリを割り当てるにLast_Nameは、格納された文字列の長さを取得しbuffer、1 を追加して null 終端バイト用のスペースを確保します。

void file2(fr *friends, const size_t num_friends, FILE *read)
{
    size_t counter = 0;
    char buffer[128];

    while (counter < num_friends && fscanf(read, "%s", buffer) != EOF) {
        friends[counter].Last_Name = malloc(strlen(buffer) + 1);
        strcpy(friends[counter].Last_Name, buffer);
        counter++;
    }
}

次に、これを次のように呼び出しますfile2(friends, 5, read);。中央の引数は、配列のサイズです。

fscanfbufferまた、提供するデータが多すぎると、オーバーフローする可能性があります。プログラムのクラッシュにつながる可能性のある境界チェックはありません。fgets次回は代わりに利用しようと思います。

于 2012-11-19T09:25:47.143 に答える