0

テキストファイルから電話番号を取り出して配列に入れるという宿題があります...これは私が書いたものですが、何も書かれていません...ループはテキストが含まれている限りです.txtファイル、配列に読み込みます。..

void get_phones(int *phones)
{
    FILE *fp;
    fp = fopen("phones.txt", "rt");
    if (fp == NULL)
    {
        printf ("Error\n");
    }
    else
    {
        while (fscanf(fp, "%d\n", &phones) > 0)
        {
            fscanf(fp, "%d\n", &phones);
        }
    } 
}
4

3 に答える 3

1

最新の更新:
テスト用:
次のコードを に追加main()し、数値 10 をファイル内の行数に変更してください。上限を自動的に計算するには、戻り値の型をget_phonestoに変更intして、while ループにカウンターを入れてみてください。

int i=0;
for(i=0;i<10;i++){
   printf("%lld\n",*(phones+i));
}

実際の値を出力するには、ポインターを参照する必要があります。それ以外の場合は、ポインターに格納されているアドレスを出力しています。そしてphones、配列の名前であることに加えて、その性質上、配列の最初の要素を指すポインターです。ポインターと配列の詳細については、このチュートリアルを参照してください。

32 ビット マシンを使用しているとし
ます。テキスト ファイルに入力 した電話番号は次のとおりです:
22121222345
678139199
111111111

22,121,222,345>=2,147,483,647 であることに注意してください。これは、int が表現できる最大数です。(unsigned int それは 2^32-1 です)。ここで、次のコードを実行しようとすると:

void get_phones(int *phones){
    FILE *fp;
    fp = fopen("phones.txt", "rt");

    if (fp == NULL)
        printf ("Error\n");
    else
        while (fscanf(fp, "%d\n", phones++) !=EOF){}

}

端末に出力される数値のリストは次のとおりです。
646385865
678139199
111111111

配列に保存される最初の数値は完全にランダムです! なんで?整数には大きすぎてオーバーフローするためです。

次に、次のバージョンを試してみます。

void get_phones(long long* phones){
    FILE *fp;
    fp = fopen("phones.txt", "rt");
        if (fp == NULL)
            printf ("Error\n");
        else
            while (fscanf(fp, "%lld\n", phones++) !=EOF){}

}


端末に表示される番号のリストは次のとおりです。
22121222345
678139199
111111111

なぜ機能するのですか? この型long longは 2^63-1 = 9,223,372,036,854,775,807 までの数値を格納できるため、

テスト済みの動作バージョン。必要に応じてデータ型を変更しlong longます。

!! コードの問題は、間違ったものをに渡していることですfscanfphonesはすでにポインターです。配列の開始点を指しています。を書き込むphone++と、現在のポインターが fscanf に渡され、ポインターが 1 つ増加します。これにより、ポインターが整数配列の次のスロットに移動します。

また、fscanfスキャンしたアイテムの数を返しますが、while ループの状態では、スキャンは既に実行されています。そのため、while ループの本体で 2 回呼び出す必要はありません。

5195551234 残念ながら、この数はまだ大きすぎunsigned longます。32 ビット マシンの場合、 と の両方に最大値 $2^{32}-1$ があるためintですunsigned long。これに関する詳細情報が必要な場合は、ウィキペディアを参照してください。代わりにlong long、コードを 32 ビット マシンで実行している場合に必要です。そうしないと、オーバーフローして誤ったデータが格納されます。

于 2012-06-05T19:55:15.410 に答える
1

long unsigned他の回答に追加するだけで、代わりに使用する必要がありますint(電話番号は5195551234のようなものだと思います-これは大きすぎますint)。

ファイル内の電話番号の最大数がわかっている場合は、次のように配列にスペースを事前に割り当てることができます。

long unsigned phones[1024];

ここでは、最大数を 1024 と想定してmallocいます。最大数がわからない場合は、(詳細についてはマニュアル ページを参照してください) を使用してオンザフライでメモリを割り当てることもできます。

関数get_phonesはおそらく、読み取った電話番号の数も返すはずです (これは、while ループのロジックが正しくないという事実に関係しています)。

于 2012-06-05T19:35:24.583 に答える
0
  1. main()make プログラムを実行するための関数が必要です(ドキュメントを参照)。
  2. int *phones割り当てられたメモリを指す必要があります。
  3. fscanf(fp, "%d\n", &phones);-- この関数を呼び出すたびに、以前に読み取った数値が書き換えられます。たとえば、読み取り後の各数値は、前の数値と同じメモリ アドレスに置かれます。
  4. これは、ループの繰り返しで fscanf を 2 回呼び出す動作の正しいロジックではありません。最初の fscanf() の結果はチェックされますが、2 番目の結果はチェックされません。
于 2012-06-05T19:24:07.810 に答える