-3

私は C と C++ の基本的な知識を持ったプログラミングの初心者です。画像分析に使用している .dat ファイルでコードを実行しようとしています。

基本的に、この .dat ファイルには、クラスターの x & y 位置と半径が含まれています。このコードを使用して、画像 (ピクセルをスケーリングした後、寸法が 200mm x 300mm) を 5mm x 5mm のグリッドに分割し、半径 = 1 の点の数と半径 = 100 の点の数を見つけようとしています。

これが私のコードです:

#include<stdio.h>
int main()
{ 
    int i=0,g,h,ng[350][250],ns[350][250],ntot[350][250];
    float a[6001],b[6001],c[6001];
    FILE *fres1, *fres2;

    for(g=5;g<=350;g=g+5)
    { 
        for(h=5;h<=250;h=h+5)
        {
            ng[g][h]=0;
            ns[g][h]=0;
            ntot[g][h]=0;   
        } 
    }

    fres1 = fopen("trial_final_1.dat","r+"); 
    fres2 = fopen("result_boxes.dat","w");

    if(fres1 == NULL)
    {
        printf("Error!! Cannot open file \n" );
        return 1;
    } 
    else
    {
        printf("File opened successfully, kindly check your folder for result_boxes file :) \n");
        fprintf(fres2,"x(mm)        y(mm)       no. of glass beads        no. of stain-less steel balls     total no. of balls \n");
        while(!feof(fres1))
        {
            fscanf(fres1,"%f %f %f",&a[i],&b[i],&c[i]);           
            g = ((a[i]/5) + 1)*5;
            h = ((b[i]/5) + 1)*5;
            if(c[i] == 100)
            {
                ng[g][h] = ng[g][h]+1;  
            }
            else
            {
                ns[g][h] = ns[g][h] + 1;
            }
            ntot[g][h] = ntot[g][h] + 1;
            ++i;
        }  
        g = 5;
        h = 5;
        for(g=5;g<=350;g=g+5)
        { 
            for(h=5;h<=250; h=h+5)
            {
                fprintf(fres2,"%d       %d            %d                        %d                            %d\n",g,h,ng[g][h],ns[g][h],ntot[g][h]);  

            }
        }
    }

    fclose(fres1);
    fclose(fres2);
    return 0;    

}

入力 .dat ファイル (つまり、「trial_final_1.dat」) には、次のようなデータが含まれています。

150.505951 0.797619 100.000000
172.327438 5.976130 100.000000
137.538651 11.089217 100.000000
151.304276 10.139803 100.000000
137.008926 13.175000 100.000000
120.400734 13.943015 1.000000
136.759262 14.199074 100.000000

コードを実行すると、最初に「ファイルが正常に開かれました。result_boxes ファイルのフォルダーを確認してください:)」という出力が表示されますが、その後、file.exe が動作を停止したというメッセージが表示されます。この問題のトラブルシューティングを手伝ってください。while(fscanf(fres1,"%f %f %f",&a[i],&b[i],&c[i])!=EOF )の代わりにも使用してみましwhile(!feof(fres1))たが、どちらの場合も出力は同じままです。

4

1 に答える 1

1

配列の境界チェックを行っていません。コードを簡単に調べると、 の境界をオーバーランしていることがわかります。このループではng、次のようにnsなります。ntot

for(g=5;g<=350;g=g+5)
{ 
    for(h=5;h<=250; h=h+5)
    {
        ...
    }
}

上記の問題は、<=代わりに を使用していること<、または配列の次元が 1 要素小さすぎることです。

またfres2、書き込み前に が有効なファイル ハンドルであるかどうかを確認したり、呼び出しがfscanf成功したことを確認したりしません。例えば:

fscanf(fres1,"%f %f %f",&a[i],&b[i],&c[i]);           
g = ((a[i]/5) + 1)*5;
h = ((b[i]/5) + 1)*5;

上記の呼び出しが失敗した場合、a[i]orb[i]に初期化されていない値を使用している可能性があり、境界チェックなしで配列インデックスとして使用し続けます。これは大惨事のレシピであり、読み取りを試みる前にループが EOF をチェックするため、おそらく常に発生するでしょう。

少なくとも、これを行う必要があります。

if( 3 != fscanf(fres1,"%f %f %f",&a[i],&b[i],&c[i]) ) break;

iもう 1 つ...値が 6001 に達するとどうなると思いますか?

于 2013-06-11T05:30:25.413 に答える