所以我正在创建一个程序(试图)给用户一个菜单,允许你创建一个项目,修改一个项目,查看所有项目,然后显示一个项目然后选择0(退出)之前关闭程序,它将文件保存为文本,我试图在程序启动之前重新加载它,但是当我查看它时,它没有显示我上次打开程序时创建的内容。
需要它在首次退出程序时创建的文本中加载已保存的数据。任何关于我做错事的想法。
#include <stdio.h>
#include <stdlib.h>
#define MAX 12
//Structed Items
struct item{
char itemname[20];
char itemdes[30];
int itemID;
int itemOH;
double itemUP;
};
// Function Declarations
int getMenu_Choice ();
int process (int choice, int count, struct item inven[]);
int add (int count, struct item inven[]);
int showall(int count, struct item inven[]);
int find(int count, struct item inven[]);
int modify(int count, struct item *inven);
int save(int count, struct item inven[]);
int load(int count, struct item inven[]);
int main (void)
{ // OPENS MAIN
// Declarations
int choice;
struct item inven[MAX];
int count = 0;
// Statements
do//
{ load (count, inven);
choice = getMenu_Choice ();
count = process (choice, count, &inven[0]);
}
while (choice != 0);
save (count, inven);
return 0;
} // CLOSE MAIN
/*============================getChoice=*/
int getMenu_Choice (void)
{ //OPEN GETCHOICE
// Declarations
int choice;
// Statements
printf("\n\n**********************************");
printf("\n MENU ");
printf("\n\t1.Add New Item To Inventory ");
printf("\n\t2.View All Items In Inventory ");
printf("\n\t3.Find An Item ");
printf("\n\t4.Search And Modify An Item");
printf("\n\t0.Exit ");
printf("\n**********************************");
printf("\nPlease Type Your Choice Using 0-4");
printf("\nThen Hit Enter: ");
scanf("%d", &choice);
return choice;
} //CLOSES GET CHOICE
/*============================process=*/
int process (int choice, int count, struct item *inven)
{// OPEN PROCESS
// Declarations
// Statements
switch(choice)
{
case 1: count = add(count, inven);
break;
case 2: showall(count, inven);
break;
case 3: find(count, inven);
break;
case 4: modify(count, inven);
break;
case 0: exit;
break;
default: printf("Sorry Option Not Offered");
break;
} // switch
return count;
} // CLOSE PROCESS
/*============================add one=*/
int add(int count, struct item *inven)
{//OPENS CREATE
// Declarations
int i;
i = count;
if (i < MAX)
{
printf("Enter the Item ID:\n");
scanf("%d", &inven[i].itemID);
printf("Enter the Item Name:\n");
scanf("%s", inven[i].itemname);
i++;
}
else {
printf("sorry there is no more room for you to add");
};
return i;
}; // CLOSE CREATE
/*============================showall=*/
int showall(int count, struct item *inven)
{
//Declarations
int i;
// Statements
for(i = 0; i < count; i++)
{
printf("\nItem ID : %d", inven[i].itemID);
printf("\nItem Name : %s", inven[i].itemname);
};
return 0;
};
/*============================find one=*/
int find(int count, struct item *inven)
{
//Declarations
int i;
int search;
int found;
printf("Enter the Item ID to search\n");
scanf("%d", &search);
for (i = 0; i < count; i++)
{
if(inven[i].itemID == search)
{
printf("\nItem ID : %d", inven[i].itemID);
printf("\nItem Name : %s", inven[i].itemname);
found = 1;
break;
}
}
if(i == count) /* Will be true if the loop executed without executing the break */
{
printf("\nSorry None existent");
};
return 0;
};
/*============================modify=*/
int modify(int count, struct item *inven)
//Declarations
{
int i;
int search;
int found;
int choice;
printf("Enter the Item ID to search\n");
scanf("%d", &search);
for (i = 0; i < count; i++)
{
if(inven[i].itemID == search)
{
printf("\nItem ID : %d", inven[i].itemID);
printf("\nItem Name : %s", inven[i].itemname);
found = 1;
printf("\n\n ****Modify Menu for %s*****", inven[i].itemname);
printf("\n\n Select a Number To Modify or 0 To Exit");
printf("\n =========================================");
printf("\n 1. Item ID Number");
printf("\n 2. Item Name");
printf("\n Enter 0-2: ");
scanf("%d", &choice);
switch(choice)
{
case 1:
printf("\nCurrent Item ID Number: %d", inven[i].itemID);
printf("\nPlease Enter The New Item ID Number: ");
scanf("%d", &inven[i].itemID);
printf("\nNew Item ID: %d", inven[i].itemID);
break;
case 2:
printf("\nCurrent Item Name: %s", inven[i].itemname);
printf("\nPlease Enter The New Item Name: ");
scanf("%s", &inven[i].itemname);
printf("\nNew Item Name: %s", inven[i].itemname);
break;
case 0: getMenu_Choice ();
break;
default: printf("Sorry Option Not Offered");
break;
} // switch
break;
}
}
if(i == count)
{
printf("\nSorry Non existent");
};
return 0;
};
/*============================Save=*/
int save(int count, struct item inven[])
{
//Declarations
int i;
FILE *fptr;
//Statements
fptr = fopen("inven.txt", "w");
for(i = 0; i < count; i++)
{
fprintf(fptr, "ID = %d\n", inven[i].itemID);
fprintf(fptr, "Name = %s\n", inven[i].itemname);
};
fclose(fptr);
return 0;
};
/*============================Load=*/
int load(int count, struct item inven[])
{
//Declarations
FILE *fptr;
int i;
count = 0;
fptr = fopen("inven.txt", "r");
for (i = 0; i < count; i++)
{
fscanf(fptr, "%d %s", &inven[i].itemID, &inven[i].itemname);
}
fclose(fptr);
return count;
};
答案 0 :(得分:0)
此代码存在一些严重问题。如果这是生产代码,我建议您使用更适合文本处理的更宽容的语言来编写它。
我将尝试涵盖基础知识。
必须检查每个文件操作,否则你会想到什么是默默无闻的。它通常是这样的。
#include <string.h> // for strerror()
#include <stdlib.h> // for exit()
#include <errno.h> // for errno
const char filename[] = "invent.txt";
fptr = fopen(filename, "r");
if( fptr == NULL ) {
fprintf( stderr, "Couldn't open %s for reading: %s\n", filename, strerror(errno) );
exit(1);
}
errno
是一个全局变量,包含最后一个文件操作的错误代码。 strerror(errno)
将其变成人类可读的东西。
然后你有这个for循环。
for (i = 0; i < count; i++)
{
fscanf(fptr, "%d %s", &inven[i].itemID, &inven[i].itemname);
}
但是你设置count = 0;
所以它永远不会运行。您还在main
中传入了0,因此无论如何它都不会运行。
您也没有检查fscanf
是否成功,所以如果该行与该格式不匹配,它会一次又一次地悄悄地重新扫描它。
您正在传递&inven[i].itemname
,但inven[i].itemname
已经是char *
指针。与int
字段不同,不需要获取它的地址。你应该只通过inven[i].itemname
。你在其他地方犯了这个错误,应该对此发出警告。如果没有,请检查是否有编译器警告。
inven[i].itemname
只有20个字符长,很容易溢出缓冲区。 %s
应始终具有与之关联的大小,例如%19s
(空字节为19 + 1为20)。
相反,我建议你这样做。
int load(const char filename[], struct item inven[], size_t max_items) {
// Open the file with error checking.
FILE *fptr = fopen(filename, "r");
if( fptr == NULL ) {
fprintf( stderr, "Couldn't open %s for reading: %s\n", filename, strerror(errno) );
exit(1);
}
// A buffer to read each line from the file
char line[1024];
// The number of items read.
int num_items = 0;
// Read each line
while( (fgets( line, 1024, fptr ) != NULL) ) {
// Don't walk off the end of the array.
// Let the user know you had to stop early.
if( num_items >= max_items ) {
fprintf( stderr, "There were more lines than space to store them" );
break;
}
// Parse the line, warn if we can't understand it.
if( sscanf(line, "%d %19s", &inven[num_items].itemID, inven[num_items].itemname) != 2 ) {
fprintf( stderr, "Could not understand '%s'\nSkipping.\n", line );
continue;
}
num_items++;
}
fclose(fptr);
return num_items;
}
然后就这样调用:
int num_items = load("inven.txt", inven, MAX);
传入文件名使功能更加灵活。由于您传入已分配的列表,因此该列表的大小也必须传入,否则该函数不知道何时停止写入列表。调用代码需要知道已填充inven
的大小,即num_items
。
这只会让load
正常工作,但其余的代码对于单个答案来说也有类似的问题。不要编写所有内容并尝试使其正常工作,而是尝试只编写load
并让load
正常工作。当它工作时,转到另一个功能。
另外需要注意的是,使用固定大小的数组和固定大小的字符串来处理数据文件并不会很好。您的字符串可能太小,而且您没有跟踪数组的长度。这一切都变得非常复杂。
相反,我建议您查看GLib,其中arrays和strings可以根据需要增长。他们也为你追踪他们的长度。
但实际上我建议用Ruby或Python等语言重写它,更适合文本处理,并为你处理内存管理。
答案 1 :(得分:0)
发布的load()
函数存在很多问题。
请查看有关问题列表的许多评论。
以下代码更正了load()函数
中的这些问题请注意对签名的更改以删除count
参数
/*============================Load=*/
int load( struct item inven[] )
{
FILE *fptr = fopen("inven.txt", "r");
if( !fptr )
{
perror( "fopen to read 'inven.txt' failed" );
return 0;
}
// implied else, fopen successful
int count = 0;
while( count < MAX && 2 == fscanf(fptr, "%d %19s",
&inven[ count ].itemID,
inven[ count ].itemname) )
{
count++;
}
fclose(fptr);
return count;
} // end function: load
答案 2 :(得分:0)
@xing那是我在程序中改变的内容,现在它无法正常加载。
#include <stdio.h>
#include <stdlib.h>
#define MAX 12
//Structed Items
struct item{//Opens Struct
char itemname[20];
char itemdes[30];
int itemID;
int itemOH;
double itemUP;
};//Closes Struct
// Function Declarations
int getMenu_Choice ();
int process (int choice, int count, struct item inven[]);
int add (int count, struct item inven[]);
int showall(int count, struct item inven[]);
int find(int count, struct item inven[]);
int modify(int count, struct item *inven);
int save(int count, struct item inven[]);
int load(int count, struct item inven[]);
int main (void)
{//OPENS MAIN
//Declarations
int choice;
struct item inven[MAX];
int count = 0;
//Statements
count = load (count, inven);
do//opens
{
choice = getMenu_Choice ();
count = process (choice, count, &inven[0]);
}//closes
while (choice != 0);
save (count, inven);
return 0;
} // CLOSE MAIN
/*============================getChoice=*/
int getMenu_Choice (void)
{//OPEN GETCHOICE
//Declarations
int choice;
// Statements
printf("\n\n**********************************");
printf("\n MENU ");
printf("\n\t1.Add New Item To Inventory ");
printf("\n\t2.View All Items In Inventory ");
printf("\n\t3.Find An Item ");
printf("\n\t4.Search And Modify An Item");
printf("\n\t0.Exit ");
printf("\n**********************************");
printf("\nPlease Type Your Choice Using 0-4");
printf("\nThen Hit Enter: ");
scanf("%d", &choice);
return choice;
}//CLOSES GET CHOICE
/*============================process=*/
int process (int choice, int count, struct item *inven)
{// OPEN PROCESS
//Statements
switch(choice)
{
case 1: count = add(count, inven);
break;
case 2: showall(count, inven);
break;
case 3: find(count, inven);
break;
case 4: modify(count, inven);
break;
case 0: exit;
break;
default: printf("Sorry Option Not Offered");
break;
}//switch
return count;
}//CLOSE PROCESS
/*============================add one=*/
int add(int count, struct item *inven)
{//opens add one
// Declarations
int i;
//Statements
i = count;
if (i < MAX)
{//opens if
printf("\nEnter the Item ID: ");
scanf("%d", &inven[i].itemID);
printf("Enter the Item Name: ");
scanf("%s", &inven[i].itemname);
printf("Enter Item Description:\n");
scanf("%s", &inven[i].itemdes);
printf("Enter Number Of Items On Hand: ");
scanf("%d", &inven[i].itemOH);
printf("Enter The Unit Price Of The Item: ");
scanf("%lf", &inven[i].itemUP);
i++;
}//closes if
else {//opens else
printf("\nSorry there seems to be no more room\n in your inventory. Please delete some current inventory.");
};
return i;
};//closes add one
/*============================showall=*/
int showall(int count, struct item *inven)
{//opens show all
//Declarations
int i;
// Statements
for(i = 0; i < count; i++)
{//opens for
printf("\nItem ID: %d", inven[i].itemID);
printf("\nItem Name: %s", inven[i].itemname);
printf("\nItem Description: %s", inven[i].itemdes);
printf("\nItems On Hand: %d", inven[i].itemOH);
printf("\nItem Unit Price: %0.2lf", inven[i].itemUP);
};//closes for
return 0;
};//closes show all
/*============================find one=*/
int find(int count, struct item *inven)
{//opens find one
//Declarations
int i;
int search;
int found;
//Statements
printf("Enter the Item ID to search\n");
scanf("%d", &search);
for (i = 0; i < count; i++)
{//opens for
if(inven[i].itemID == search)
{//opens if
printf("\nItem ID: %d", inven[i].itemID);
printf("\nItem Name: %s", inven[i].itemname);
printf("\nItem Description: %s", inven[i].itemdes);
printf("\nItems On Hand: %d", inven[i].itemOH);
printf("\nItem Unit Price: %0.2lf", inven[i].itemUP);
found = 1;
break;
}//closes if
}//closes for
if(i == count)
{//opens if
printf("\nSorry That Item Isn't in OUR Inventory.");
};//closes if
return 0;
};//closes find one
/*============================modify=*/
int modify(int count, struct item *inven)
{//opens modify
//declarations
int i;
int search;
int found;
int choice;
printf("Enter the Item ID to search\n");
scanf("%d", &search);
for (i = 0; i < count; i++)
{//opens for
if(inven[i].itemID == search)
{//opens if
printf("\nItem ID: %d", inven[i].itemID);
printf("\nItem Name: %s", inven[i].itemname);
printf("\nItem Description: %s", inven[i].itemdes);
printf("\nItems On Hand: %d", inven[i].itemOH);
printf("\nItem Unit Price: %0.2lf", inven[i].itemUP);
found = 1;
printf("\n\n ****Modify Menu for %s*****", inven[i].itemname);
printf("\n\n Select a Number To Modify or 0 To Exit");
printf("\n =========================================");
printf("\n 1. Item ID Number");
printf("\n 2. Item Name");
printf("\n 3. Item Description");
printf("\n 4. Item Unit Price");
printf("\n 5. Items On Hand");
printf("\n Enter 0-5: ");
scanf("%d", &choice);
switch(choice)
{
case 1:
printf("\nCurrent Item ID Number: %d", inven[i].itemID);
printf("\nPlease Enter The New ID Number: ");
scanf("%d", &inven[i].itemID);
printf("\nNew Item ID: %d", inven[i].itemID);
break;
case 2:
printf("\nCurrent Item Name: %s", inven[i].itemname);
printf("\nPlease Enter The New Name: ");
scanf("%s", &inven[i].itemname);
printf("\nNew Item Name: %s", inven[i].itemname);
break;
case 3:
printf("\nCurrent Item Description:\n%s", inven[i].itemdes);
printf("\nPlease Enter The New Description:\n");
scanf("%s", &inven[i].itemdes);
printf("\nNew Item Description:\n%s", inven[i].itemname);
break;
case 4:
printf("\nCurrent Item Unit Price: %0.2lf", inven[i].itemUP);
printf("\nPlease Enter The New Unit Price: ");
scanf("%lf", &inven[i].itemUP);
printf("\nNew Item Unit Price: %0.2lf", inven[i].itemUP);
break;
case 5:
printf("\nCurrent Items On Hand: %d", inven[i].itemOH);
printf("\nPlease Enter The New On Hand Amount: ");
scanf("%d", &inven[i].itemOH);
printf("\nNew Amount Of Items On Hand: %d", inven[i].itemOH);
break;
case 0: getMenu_Choice ();
break;
default: printf("Sorry Option Not Offered");
break;
}//closes switch
break;
}//closes if
}//closes for
if(i == count)
{//opens if
printf("\nSorry Non existent");
};//closes if
return 0;
};//closes modify
/*============================Save=*/
int save(int count, struct item inven[])
{
//Declarations
int i;
FILE *fptr;
//Statements
fptr = fopen("inven.txt", "w");
for(i = 0; i < count; i++)
{
fprintf(fptr, "ID = %d\n", inven[i].itemID);
fprintf(fptr, "Name = %s\n", inven[i].itemname);
fprintf(fptr, "Des = %s\n", inven[i].itemdes);
fprintf(fptr, "On Hand = %d\n", inven[i].itemOH);
fprintf(fptr, "Unit Price = %lf\n", inven[i].itemUP);
};
fclose(fptr);
return 0;
};
/*============================Load=*/
int load(int count, struct item inven[])
{
//Declarations
FILE *fptr;
if ( ( fptr = fopen("inven.txt", "r")) == NULL) {
fprintf ( stderr, "could not open inven.txt\n");
return 0;
}
while ( ( fscanf(fptr, " ID = %d Name = %s Des = %s On Hand = %d Unit Price = %lf", &inven[count].itemID, inven[count].itemname, inven[count].itemdes, &inven[count].itemOH, &inven[count].itemUP)) == 2)
{
count++;
if ( count >= MAX) {
break;
}
}
fclose(fptr);
return count;
}