簡體   English   中英

在while循環中無限循環

[英]infinite loop in while loop

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,產品是結構中名為PRODUCT,stockquant和stockorderquant ara變量的Struct的實例。 我正在嘗試更改stockquant和stockorderquant的值。 這是我為我的項目所做的批量更新。 我試圖在編輯每個產品的庫存數量和訂單數量時瀏覽整個名為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;

讓我引用fopen的手冊頁:

讀寫可以以任何順序混合在讀/寫流上。 請注意,除非輸入操作遇到文件結尾,否則ANSI C要求在輸出和輸入之間插入文件定位功能。 (如果不滿足此條件,則允許讀取操作返回除最近操作以外的寫入結果。)因此,將fseek(3)fgetpos(3)在此類流上進行讀寫操作之間的操作。 此操作可能是明顯的無操作(如
fseek(..., 0L, SEEK_CUR)要求其同步副作用。

寫完后調用fseek

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

應該修復它。

問題是

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

將當前指針sizeof(prod)移到當前文件指針之前,下一次讀取將讀取同一條記錄,並向前移動等。

Hece,無限循環。

實際上,它始終只讀取第一條記錄。

這句話

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

正在嘗試存儲稱為product的結構,而不是在文件中存儲prod ,並且可能正在返回錯誤(未檢查),該錯誤將阻止指針移至下一條要讀取的記錄,從而使該代碼一次又一次讀取同一條記錄。

您應該存儲剛剛更改的prod變量,並且不要忘記檢查錯誤

if (fwrite (&prod, sizeof(prod), 1, fp)==-1)
    perror("fwrite error");

-sizeof(prod)會出現問題,因為sizeof返回一個無符號值。 取反時,它變成一個很大的值,然后隱式將其long intlong int

嘗試這個:

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

另外,您需要測試fwrite成功,否則將繼續倒帶。

我相信您有一個無限循環,您總是在搜索文件位置指示器:

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

因此,您先閱讀一個元素,然后重新搜索它,並始終無限地閱讀同一元素。

fseek()的第二個默認參數類型為'long'。 您需要將其強制轉換為“ long”,即fseek(fp,-(long)sizeof(prod),SEEK_CUR);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM