最新の更新:
テスト用:
次のコードを に追加main()
し、数値 10 をファイル内の行数に変更してください。上限を自動的に計算するには、戻り値の型をget_phones
toに変更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
ます。
!! コードの問題は、間違ったものをに渡していることですfscanf
。phones
はすでにポインターです。配列の開始点を指しています。を書き込むphone++
と、現在のポインターが fscanf に渡され、ポインターが 1 つ増加します。これにより、ポインターが整数配列の次のスロットに移動します。
また、fscanf
スキャンしたアイテムの数を返しますが、while ループの状態では、スキャンは既に実行されています。そのため、while ループの本体で 2 回呼び出す必要はありません。
5195551234 残念ながら、この数はまだ大きすぎunsigned long
ます。32 ビット マシンの場合、 と の両方に最大値 $2^{32}-1$ があるためint
ですunsigned long
。これに関する詳細情報が必要な場合は、ウィキペディアを参照してください。代わりにlong long
、コードを 32 ビット マシンで実行している場合に必要です。そうしないと、オーバーフローして誤ったデータが格納されます。