1

構造体の配列を作成し、その構造体の配列をファイルに保存してから、そのファイルを開き、そのファイルを読み取り、そのファイルの内容を構造体の配列にコピーする必要がある C でプログラムを作成しています (この「friend」と呼ばれる特定の構造体は 3 つの文字列を保持します)。ただし、配列が次のように 3 つのフレンドを保持している場合:

John Doe 234-1230 (string, string, string) <br>
Kool Kat 343-3413<br>
Suzie Q 234-1234<br>

この配列をファイルに保存し、以下の open 関数を使用して開くと、次のようになります。

Joán Doe 234-2132<br>
Kool Kat 343-3413<br>
Suzie Q 234-1234<br>

また

John Doe 234-2132<br>
Kool Kat 343-3413<br>
Suz Q 234-1234<br>

ここで、1 つの文字列 (ほとんどの場合、構造体の最初の文字列) は、1 つまたは複数のランダムな文字が切り替わったものとほぼ同じです。誰でもこのエラーの原因を教えてもらえますか?

void open(friend* book, int* size){
   FILE *pRead;
   char address[100];
   char answer = 'a';
   printf("\nWARNING: Any unsaved data in the current phonebook will be lost!");
   printf("\nType the file-name you would like to open(press '1' for the default location):");
   scanf("%s", &address);

   if(strcmp(address, "1") == 0){
      strcpy(address, "default.dat");
   }

   pRead = fopen(address, "r");
   if(pRead == NULL){
      printf("\nFile not opened\n");
   }else{
      int counter = 0;
      while(!feof(pRead)){
         fscanf(pRead, "%s%s%s", book[counter].pFName, book[counter].pLName, book[counter].pNumber);
         counter++;
         realloc(book, sizeof(friend) * counter);
      }
      *size = counter;
      fclose(pRead);
      printf("\n%s has been loaded into the program!", address);
   }
}

その他の情報: 同じファイルに対してこの関数を呼び出し続けると、最終的には正しい文字列が生成されるため、保存関数が正しいと思われます。これはメモリ割り当てと関係がありますか?

ここに私の構造体コードがあります:

typedef struct Contact{ //creates a struct that holds three strings (first name, last name, phone number) (can be referred to as either Contact or friend
   char pFName[20]; //first name of friend
   char pLName[20]; //last name of contact
   char pNumber[12]; //phone number of contact
}friend;
4

2 に答える 2

2

ここに明確な問題があります。

  while(!feof(pRead)){
     fscanf(pRead, "%s%s%s", book[counter].pFName, book[counter].pLName, book[counter].pNumber);
     counter++;
     realloc(book, sizeof(friend) * counter);
  }

あなたは常に自分が所有していないメモリを読み込んでから、realloc後で尋ねます。また、 からの戻り値を無視しますrealloc。NULL になることはないと想定していても、データを再配置することはできます。これを行う方が安全です:

  while(!feof(pRead)){
     book = realloc(book, sizeof(friend) * (counter+1));
     fscanf(pRead, "%s%s%s", book[counter].pFName, book[counter].pLName, book[counter].pNumber);
     counter++;
  }

ここで、それが変更される可能性があることを受け入れると、bookそれを double ポインターとして渡すか、関数に返す必要があります。

feofテスト、 の戻り値をチェックしていないという事実fscanf、およびバッファオーバーフローから保護していないという事実など、避けるべきことがここには他にもあります。しかし、あなたのインプットとアウトプットを見ると、これらのどれもが今あなたに直接影響しているとは思いません。

于 2013-10-31T21:36:24.820 に答える
0

ファイル名を読み取っているときにscanf関数にエラーがあります。

scanf("%s", &address);

& を削除する必要があります。

ただし、これはほとんどのシステムで機能するため、おそらく問題の原因ではありません。基本的にここでの問題はscanf("%s", &string)、 scanf が型を期待している間に、 char[256] へのポインターに減衰することchar *です。ポインタ&string&string[0]が同じように表されるため、機能します。ただし、コードは、別のシステムでは異なる動作をする可能性がある標準 C によって保証されていないものに依存しています。

于 2013-10-31T21:27:22.573 に答える