2
fp=fopen("Product.dat","rb+");
while (fread(&prod,sizeof (prod),1,fp)==1) {
    prod.stockquant = prod.stockquant + prod.stockorderquant;
    prod.stockorderquant = 0;
    fseek(fp, -sizeof(prod), SEEK_CUR);
    fwrite (&prod, sizeof(prod), 1, fp);
}
fclose (fp);

while ループに入ると、無限ループになります。ファイル ポインタは fp で、prod は PRODUCT と呼ばれる構造体のインスタンスであり、構造体内の変数 stockquant および stockorderquant です。stockquant と stockorderquant の値を変更しようとしています。これは、私のプロジェクトで行っているバッチ更新です。各製品のstockquantとorderquantを編集しながら、product.datというファイル全体を調べようとしています。

無限ループになるのはなぜですか? このメソッドは、prod.id = userinput かどうかをチェックする if ステートメントで使用すると機能するようです。

何か助けはありますか?

追加のコード:

void batchupdate(void) { 
    system("cls");
    FILE *fp;
    int c=0;
    gotoxy(20,4);
    printf("****Batch Update Section****");
    char another='y';
    while(another=='y')
    {
        system("cls");
        gotoxy(15,6);
        printf("Are you sure you want to Batch update (Press Y or N)?");

        if((getch()=='y') || (getch() == 'Y')) {
        system("cls");
        int pos;

        fp=fopen("Product.dat","rb+");
        while(fread(&prod,sizeof(prod),1,fp)==1) {
                prod.stockquant = prod.stockquant + prod.stockorderquant;
                product.stockorderquant = 0;

                fseek(fp, -(sizeof(prod)), SEEK_CUR);
                fwrite (&prod, sizeof(prod), 1, fp);
                getchar();
                pos = ftell(fp);
                printf("%d",&pos);


        }
        fclose (fp);

        gotoxy(15,16);
        printf("Complete");
        gotoxy(15,18);
        printf("All products stock quantity have been updated. The stock order quantity has been reset");

        gotoxy(15,16);
        printf("Do you want to modify another product?(Y/N)");
        fflush(stdin);
        another=getch() ; }

    else { if((getch()=='n') || (getch() == 'N')) {
                mainmenu();
           }
    }
}
    returnfunction();
}

これが私の製品のリスト方法です (そしてうまくいきます!) (ここに表示される注文数量は、stockorderquant とは関係ありません。

void listproduct(void)  
{
    int x;
    FILE *fp;
    system("cls");
    gotoxy(1,1);
    printf("*********************************Product List*****************************");
    gotoxy(2,2);
    printf("Name              ID    Price  StockQuant  Order Quant  Description");
    x=4;
    fp=fopen("Product.dat","rb");
    while(fread(&prod,sizeof(prod),1,fp)==1){
        gotoxy(2,x);
        printf("%s",prod.prodname);
        gotoxy(20,x);
        printf("%d",prod.prodid);
        gotoxy(26,x);
        printf("%.2f",prod.price);
        gotoxy(34,x);
        printf("%d",prod.stockquant);
        gotoxy(46,x);
        printf("%d",prod.orderquantity);
        gotoxy(59,x);
        printf("%s",prod.description);
        printf("\n\n");
        x++;
    }
    fclose(fp);
    gotoxy(35,25);
    returnfunction();
}

私の構造体は以下のように定義されています:

struct PRODUCT
{
    int id;
    char name[30];
    char desc[50];
    float price;
    int stockquant;
    int orderquant;
    int stockorderquant;
};

struct PRODUCT prod;
4

6 に答える 6

3

のマニュアルページを引用させてくださいfopen

読み取りと書き込みは、任意の順序で読み取り/書き込みストリームに混在させることができます。ANSI C では、入力操作でファイルの終わりが検出されない限り、ファイル ポジショニング関数が出力と入力の間に介入する必要があることに注意してください。(この条件が満たされない場合、読み取りは最新以外の書き込みの結果を返すことができます。) したがって、書き込み操作と読み取り操作の間にfseek(3)or操作を配置することをお勧めします (Linux では実際に必要な場合もあります)。fgetpos(3)そんな流れ。この操作は、明らかなノーオペレーションである可能性があります (
fseek(..., 0L, SEEK_CUR)同期の副作用のために呼び出されます。

fseek書き込み後に呼び出し、

fseek(fp, -sizeof(prod), SEEK_CUR);
fwrite (&prod, sizeof(prod), 1, fp);
fseek(fp, 0, SEEK_CUR);

それを修正する必要があります。

于 2013-01-10T01:36:37.580 に答える
2

問題はそれです

fseek(fp, -sizeof(prod), SEEK_CUR);

現在のポインタを現在のファイルポインタの前に移動しsizeof(prod)、次の読み取りで同じレコードを読み取り、前に移動します。

Hece、無限ループ。

実際には、常に最初のレコードのみを読み取ります。

于 2013-01-10T01:21:22.717 に答える
1

fwrite (&product, sizeof(prod), 1, fp);

productは、ファイルではなくという構造体を格納しようとしprodています。エラー (チェックされていない) が返される可能性があります。これにより、ポインターが次の読み取りレコードに移動できなくなり、このコードが何度も同じレコードを読み取ってしまいます。

変更したばかりの変数を保存し、prodエラーをチェックすることを忘れないでください

if (fwrite (&prod, sizeof(prod), 1, fp)==-1)
    perror("fwrite error");
于 2013-01-10T01:27:43.200 に答える
0

私はあなたが無限ループを持っていると信じています、あなたは常にファイル位置インジケーターを探します:

fseek(fp, -sizeof(prod), SEEK_CUR);

したがって、1つの要素を読み取ってからそれを再検索し、常に同じ要素を無限に読み取ります。

于 2013-01-10T01:28:51.027 に答える
0

は符号なしの値を返す-sizeof(prod)ため、値に問題があります。sizeofこれを否定すると、非常に大きな値になり、暗黙的に にキャストしlong intます。

これを試して:

fseek(fp, -(int)sizeof(prod), SEEK_CUR);

また、fwrite成功したか、巻き戻しを続けるかをテストする必要があります。

于 2013-01-10T01:26:40.603 に答える