【发布时间】:2014-06-09 12:31:18
【问题描述】:
问题的标题很好地解释了这种情况。我不习惯使用文件和相关命令(例如 fseek、fwrite 等)。
无论如何,以下程序必须模拟一个菜单,并为用户提供添加、编辑、删除或显示文件记录的选择。这是一个相当简单的任务,但我无法弄清楚我做错了什么。
#include <stdio.h>
typedef struct{
int code;
char description[100];
int volume;
}product;
int main() {
int pick =0, i;
product *p;
FILE *filePtr;
void add(FILE *filePtr, product* p);
void removal(FILE *filePtr, product* p);
void show(FILE *filePtr, product* p);
void edit(FILE *filePtr, product* p);
void description(FILE *filePtr, product* p);
if ( ( filePtr = fopen( "stock.dat", "rb+")) == NULL ) {
printf("The file could not be read");
}
else {
do{
printf(" ************ MAIN MENU ************\n");
printf(" ** -------------welcome------------- **\n");
printf(" ** ** \n");
printf("* Please select one of the commands below *\n");
printf("********************************************\n");
printf("* Press 1 to remove products from the list *\n");
printf("* Press 2 to change a product's quantity *\n");
printf("* Press 3 to add a new product to the list *\n");
printf("* Press 4 to view product list *\n");
printf("* Press 5 to exit the programm *\n");
printf("********************************************\n");
scanf("%d", &pick);
switch ( pick ) {
case 1:
removal(filePtr, p);
break;
case 2:
edit(filePtr, p);
break;
case 3:
add(filePtr, p);
break;
case 4:
show(filePtr, p);
break;
default:
printf("Error! Please enter a correct number");
break;
}
}while (pick != 5);
}
fclose(filePtr);
return 0;
}
void removal(FILE *fileptr, product * p) {
int code;
product empty = { 0, " ", 0 };
printf("\n\nYou are about to delete a record, please enter the product's code");
scanf("%d", &code);
fseek( fileptr, (code - 1) * sizeof(p), SEEK_SET);
fread( &p->code, sizeof(p), 1, fileptr);
if (p->code == 0){
printf("Product code not found, please retry");
} else {
fseek( fileptr, (code -1) * sizeof(p), SEEK_SET);
fwrite( &empty, sizeof(p), 1, fileptr);
printf("Code was found, product removed successfully\n\n");
}
}
void add(FILE *fileptr, product * p){
int code, quantity;
printf("You are about to add a new product in the list\n Please input the product's code\n");
scanf("%d", &code);
fseek( fileptr, (code-1) * sizeof(p), SEEK_SET);
fread(&code, sizeof(p), 1, fileptr);
fseek(fileptr, (code-1) * sizeof(p), SEEK_SET);
fwrite( &code, sizeof(p), 1, fileptr);
printf("Now enter the product's remaining quantity");
scanf("%d", &quantity);
fseek(fileptr, (quantity-1) * sizeof(p), SEEK_SET);
fwrite( &quantity, sizeof(p), 1, fileptr);
}
void edit(FILE *fileptr, product * p){
int code, volume;
printf("\nYou are about to edit a existing product's quantity\n Please enter the product's code\n");
scanf("%d", &code);
fseek(fileptr, (code -1) * sizeof(p), SEEK_SET);
fread(&code, sizeof(p), 1, fileptr);
if (p->code == 0){
printf("\nThe code you entered is not in the list, please retry\n");
}else{
printf("\nCode found!\n Product's current quantity is %d", &p->volume);
printf("\n Please enter the new quantity");
scanf("%d", &volume);
p->volume = volume;
fseek(fileptr, (volume -1) * sizeof(p), SEEK_SET);
fwrite(&volume, sizeof(p), 1, fileptr);
}
}
void show(FILE *fileptr, product * p){
int i=1;
printf("\n\n\n ****SHOWING ALL PRODUCTS****\n\n\n");
printf("PRODUCT CODE QUANTITY IN STOCK\n");
while (i<100 && !feof(fileptr)){
fscanf( fileptr, "%d%d", &p->code, &p->volume);
printf("%d %d\n", &p->code, &p->volume);
fseek(fileptr, (p->code + 1) * sizeof(p), SEEK_SET);
fscanf( fileptr, "%d%d", &p->code, &p->volume);
i++;
}
printf("You may scroll back up to view the list\n\n");
}
为了了解正在发生的事情:如果用户输入选项 4,程序不会显示任何记录,而是显示随机值,但即使用户选择添加产品(通过选择选项 3,即add 函数),以后不会显示,因此即使用户选择删除也不能删除。同样,我在编程方面相当陌生(我相信你经常听到这个:P)。我之前也发过类似的问题,但没有得到解决方案。
编辑 我编辑了大部分代码,基本上文件以二进制形式打开,现在结构产品 p 传递给每个函数。现在据说问题已解决,程序运行一次显示正确的值和记录,但由于未知原因自行崩溃。任何额外的帮助都会很棒
【问题讨论】:
-
典型的
stock.dat文件是什么样的? -
我已经编辑了您的问题并尝试缩进您的代码。我能够这样做,直到
removal()函数结束。此后,大括号不再匹配。请看一下您的代码。此外,您需要更好地调试代码,以便在此处提供最少的代码以供其他人帮助。 -
我已删除您代码中的空白行并正确缩进。他们现在都走了。更重要的是,您的代码不再反映原始问题。您应该保留原始代码,并将新代码添加为编辑,或者应该使用新代码打开一个新问题。
-
不使用
!feof(fileptr),而是检查fscanf()的结果,如果返回值为EOF,则采取相应措施。 -
在许多地方,代码在执行用户 IO 时没有检查
scanf()的结果,如scanf("%d", &code);。这很容易出现问题。最好检查结果。最好使用fgets()并后处理读取缓冲区。