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 的 Struct 实例,stockquant 和 stockorderquant 都是 struct 中的变量。我正在尝试更改 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)或操作是一种很好的做法(在 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

您将遇到值问题,-sizeof(prod)因为sizeof返回一个无符号值。当你否定它时,它变成一个非常大的值,然后你隐式地将它转换为long int.

试试这个:

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

此外,您需要测试您是否fwrite成功,否则您将继续倒带。

于 2013-01-10T01:26:40.603 回答
0

我相信你有一个无限循环,你总是重新寻找文件位置指示器:

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

因此,您阅读了一个元素,然后重新搜索它,并且始终无限地阅读相同的元素。

于 2013-01-10T01:28:51.027 回答
0

'long' 中 fseek() 的第二个默认参数类型。您需要将其类型转换为“long”,即 fseek(fp, -(long) sizeof(prod), SEEK_CUR);

于 2016-09-22T07:02:50.620 回答