对于C
中的文件和记录,我有点新,而且我正在处理一个项目。以下程序必须为用户提供编辑,添加,删除和查看文件中所有记录的选项。
#include <stdio.h>
typedef struct {
int code;
char description[100];
int volume;
} product;
void addition(FILE *filePtr);
void removal(FILE *filePtr);
void showcase(FILE *filePtr);
void edit(FILE *filePtr);
void description(FILE *filePtr);
int main() {
int pick, i;
product p = { 0, "", 0 };
FILE *filePtr;
if ( ( filePtr = fopen( "stock.dat", "a+") ) == NULL ) {
printf("The file could not be read");
} else {
for( i = 0; i < 100; i++ )
fwrite( &p, sizeof(p) , 1 , filePtr) ;
fclose(filePtr) ;
while ( !feof( filePtr)) {
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 change a product's description*\n");
printf("********************************************\n");
scanf("%d", &pick);
switch ( pick ) {
case 1:
removal(filePtr);
break;
case 2:
edit(filePtr);
break;
case 3:
addition(filePtr);
break;
case 4:
showcase(filePtr);
break;
case 5:
description(filePtr);
break;
default:
printf("Error! Please enter a correct number");
break;
}
}
}
return 0;
}
void removal(FILE *cfPtr) {
product p;
int code, volume;
product empty = { 0, "", 0 };
cfPtr = fopen("stock.dat", "a");
printf("\nYou are about to remove a product from the list\n");
printf("Please type that product's code\n");
scanf("%d", &code);
fseek(cfPtr, (p.code - 1)*sizeof(p), SEEK_SET);
fread(&p, sizeof(p), 1, cfPtr);
if (code == 0) {
printf("\nProduct code %d not found, please try again\n", &code);
} else {
printf("\nProduct found! Record is being deleted...");
fseek(cfPtr, (p.code - 1)*sizeof(p), SEEK_SET);
fwrite(&empty, sizeof(p), 1, cfPtr);
printf("\nRecord succesfully deleted!\n");
}
fclose(cfPtr);
}
void addition(FILE *cfPtr) {
product p;
int code, quantity;
printf("You are about to add a new product in the list\n");
cfPtr = fopen("stock.dat", "a");
printf("Please input the product's code that you wish to add\n");
fscanf( stdin, "%d", &p.code);
printf("Now input the available quantity of the product that is in stock\n");
fscanf(stdin, "%d", &p.volume);
fseek( cfPtr, (p.code - 1) * sizeof(p), SEEK_SET);
fseek( cfPtr, (p.volume - 1) * sizeof(p), SEEK_SET);
fwrite(&code, sizeof(p), 1, cfPtr);
fwrite(&quantity, sizeof(p), 1, cfPtr);
printf("\n\nThe Product with code %d and quantity of %d has been added succesfully\n\n", p.code, p.volume);
fclose(cfPtr);
}
void showcase(FILE *cfPtr){
product p;
int i;
cfPtr = fopen("stock.dat", "a");
printf("\n\n\n ****SHOWING ALL PRODUCTS****\n\n\n");
printf("PRODUCT CODE QUANTITY IN STOCK");
for (i=0; i=100; i++) {
printf("\n%d", p.code);
printf(" %d\n", &p.volume);
}
fclose(cfPtr);
}
void edit(FILE *cfPtr){
product p;
int code, volume;
cfPtr= fopen("stock.dat", "a");
printf("\n\n\n\You are about to edit a product's quantity\n");
printf("Please enter that product's code\n");
scanf("%d", &code);
while ( !feof( cfPtr)) {
fseek(cfPtr, ( code - 1)*sizeof(p), SEEK_SET);
fread( &code, sizeof(p), 1, cfPtr);
if (code = p.code){
printf("Product %d was found! current quantity: %d\n", &code, &p.volume);
printf("Please enter the new quantity of the product\n");
scanf("%d", &volume);
fseek(cfPtr, ( volume - 1)*sizeof(p), SEEK_SET);
fwrite( &p, sizeof(p), 1, cfPtr);
printf("List has been updated, product %d has now %d units\n\n", &code, &volume);
break;
} else {
printf("Product code %d was not found please try again", &code);
}
}
fclose(cfPtr);
}
void description(FILE *cfPtr) {
product p;
char desc;
int i, code, check=0;
cfPtr= fopen("stock.dat", "a");
printf("\n You are about to change a product's description\n");
printf("Please enter the product's code");
scanf("%d", &code);
for (i=0; i=100; i++) {
fseek( cfPtr, (code -1)*sizeof(p), SEEK_SET);
fread( &code, sizeof(p), 1, cfPtr);
if (code = p.code) {
printf("\nCode found, now please enter the description");
scanf("%c", &desc);
p.description[i] = 'desc';
fwrite( &p, sizeof(p), 1, cfPtr);
check = 1;
}
}
if (check != 1){
printf("Code not found! Please try again");
}
}
这不是最终的代码,它肯定会有很多错误,但是我最关心的是以下代码行:
void showcase(FILE *cfPtr) {
product p;
int i;
cfPtr = fopen("stock.dat", "a");
printf("\n\n\n ****SHOWING ALL PRODUCTS****\n\n\n");
printf("PRODUCT CODE QUANTITY IN STOCK");
for (i=0; i<100; i++) {
printf("\n%d", p.code);
printf(" %d\n", &p.volume);
}
fclose(cfPtr);
}
当此部分运行时,程序会一直运行并且不间断,显示无意义的记录。我已经为此工作了2天,我已经尽力研究,但是我自己找不到解决方案。再一次,我对此非常陌生,当然我的愚蠢错误可能会引起很多仇恨。无论如何,我会非常感谢我所做错的一些暗示,使程序无法正确保存记录并告诉他们。
提前致谢:)
更新 上述函数修复了一个小错误,但代码仍然无法保存新写入的记录..
答案 0 :(得分:2)
for (i=0; i=100; i++) {
=
是作业。在每次迭代之前,i
会被赋值100
。
您想使用比较运算符,可能是<
:
for (i=0; i<100; i++) {
答案 1 :(得分:1)
for (i=0; i=100; i++) {
printf("\n%d", p.code);
printf(" %d\n", &p.volume);
}
问题出在这里。
您可能打算键入for(i = 0 ; i < 100 ; i++)
,这样它就会循环100次
它现在做的实际上只是检查他是否可以将100的值放在i中,并且由于没有错误,因为他继续,在这种情况下它将是无限循环:P
另请注意,product p
变量不会通过循环更改(甚至没有初始化),因此您基本上打印相同的值 - 而不仅仅是任何值,垃圾值(垃圾值是找到的)在该变量的内存中,因为没有变量在C中初始化为零,它们都从内存中的那个点获得一些垃圾值)100次:P
请记住这一点。
答案 2 :(得分:0)
对于每一行。
p.description[i] = 'desc';
错了。我不确定你要用这个做什么。我猜是要复制字符串&#34; desc&#34;进入描述char数组。这有两个问题。首先,您必须使用双引号来表示字符串文字,单引号表示字符文字,它只能是一个字符。区别在于&#34;&#34;还会分配一个NULL终止符来表示字符串的结尾。
e.g。
char* mystr = "This is my string";
char p = 'p';
char nullchar = '\0';
其次,您不能使用equals运算符将字符串分配给字符数组(除非您在循环中逐字符分配它)。您必须复制字符串。
strcpy(p.description, "desc");
请注意,对于其他字符串,您需要检查它们是否超出了数组的100个字符限制。您可以使用strncpy或snprintf来实现此目的。
另外,为什么要将文件指针传递给所有动作函数,然后在每个函数中再次打开文件?
此代码存在许多问题,我的建议是将所有输入的值保存在内存中,直到程序退出并且当时写入文件。如果您只是将其保存在内存中,则无需在每次添加后执行此操作。除非当然还有其他东西在读这个文件吗?
您还应该考虑保存文件的格式。您正尝试将结构本身写入文件中由用户输入决定的偏移量。如果有人输入了非常大的代码或音量值会怎样?
您可以考虑为您的产品考虑内存存储的链接列表,或者如果会有很多产品,则会在产品代码上编制索引的哈希表(使用C的缺点是这些东西不会出现在&#39 ; t作为语言的一部分)会更快。另一种选择是一个简单的数据库(sqlite),最后在写出文件时你可以考虑一种人类可读的格式,例如
<code> <description> <volume>
每个条目。 e.g。
1&#34;我的产品&#34; 10 2&#34;我的其他产品&#34; 25
当您的程序启动时,您解析文件并将其转换为内存表示,然后修改它,然后当您退出时回写更新的列表。