【发布时间】:2018-03-21 21:07:55
【问题描述】:
好的,我知道代码可能很长,但我尽可能地减少了它。我希望代码能够正常工作,这样您就可以重新创建我的问题。我的问题是,当我尝试读取文本文件时,它并没有读取所有项目。好像只看了最后几篇。我可能在没有注意到的情况下不小心改变了一些东西,因为它以前工作得很好。当您在程序中并注册项目时,它会很好地计算项目。但是当您打开文件时,您刚刚保存了您的项目。它计算的项目数少于实际文件中的项目数,并且数组都出错了。如果有人能在我的代码中看到问题,那将不胜感激。
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define MAX 20
struct items
{
int itemnumber;
char name[30];
int balance;
};
void open_file(FILE *enter_filename, char filename[], struct items aItems[], int *num_items)
{
int i=0;
printf("Choose filename (.txt).\n");
scanf("%19s", filename);
enter_filename=fopen(filename, "r+");
if(enter_filename)
{
while(!feof(enter_filename))
{
for(i = 0; i < *num_items; i++)
{
fscanf(enter_filename, "Itemnumber: %d\n", &aItems[i].itemnumber);
fscanf(enter_filename, "Name: %s\n", aItems[i].name);
fscanf(enter_filename, "Balance: %d\n", &aItems[i].balance);
}
if(!feof(enter_filename))
{
*num_items=*num_items + 1;
}
}
printf("\nNumber of items: %d \n",*num_items);
fclose(enter_filename);
}
else
{
printf("That file doesn't exist! Create a new one.\n");
printf("What name do you want for your new file?\n");
scanf("%19s", filename);
enter_filename=fopen(filename, "w+");
printf("File is created!\n");
*num_items = 0;
fclose(enter_filename);
}
}
void register_item(struct items *aItems, int *num_items)
{
int success=1;
if(*num_items < MAX)
{
while(1)
{
printf("Item number:\n");
scanf("%d", &aItems[*num_items].itemnumber);
for(int i=0; i < *num_items; i++)
{
if(aItems[*num_items].itemnumber == aItems[i].itemnumber)
{
printf("Item number already exists, choose a unique item number.\n");
success=0;
break;
}
else
{
success=1;
}
}
if(success)break;
}
printf("Name:\n");
scanf("%29s", aItems[*num_items].name);
strlwr(aItems[*num_items].name);
printf("Balance:\n");
scanf("%d", &aItems[*num_items].balance);
*num_items+=1;
}
}
void print_item(struct items aItems[], int num_items)
{
int i;
for (i=0; i < num_items; i++)
{
printf("%d. Item number: %d Name: %s Balance: %d\n", i+1, aItems[i].itemnumber, aItems[i].name, aItems[i].balance);
}
}
void quit_program(char filename[], struct items aItems[], int *num_items)
{
FILE *fil;
fil=fopen(filename, "w+");
int i;
for(i = 0; i < *num_items; i++)
{
fprintf(fil, "Itemnumber: %d\n", aItems[i].itemnumber);
fprintf(fil, "Name: %s\n", aItems[i].name);
fprintf(fil, "Balance: %d\n\n", aItems[i].balance);
}
fclose(fil);
}
int main(void)
{
FILE *enter_filename;
struct items aItems[MAX];
int menu, num_items=0;
char filename[20];
open_file(enter_filename,filename, aItems, &num_items);
while(menu!=3)
{
printf("\n");
printf("1. Register new items to inventory.\n");
printf("2. Print all items from inventory.\n");
printf("3. Quit\n");
scanf("%d", &menu);
if(menu==1)
{
register_item(aItems, &num_items);
}
if(menu==2)
{
print_item(aItems, num_items);
}
if(menu==3)
{
quit_program(filename, aItems, &num_items);
}
}
return 0;
}
【问题讨论】:
-
我不明白这怎么可能是minimal reproducible example 用于读取文件的问题。也许从头开始创建一个?一般来说,我推荐阅读How to debug small programs。
-
参见Why is “while ( !feof (file) )” always wrong?。这是一个非常糟糕的模式。另外,请考虑显示它应该读取的文件的一部分。
-
如果我从中删除更多代码或尝试从头开始制作,这将是一个不同的程序。我只添加了运行程序所需的东西。
-
是的,但大部分代码都是关于交互式提示用户输入内容,这似乎与问题无关。另外,对于任何必须测试它以确定需要什么样的输入的人来说,这很烦人。对一些项目进行硬编码,将它们写出来,再次读入,然后打印出来。
-
FILE *enter_filename; ... open_file(enter_filename, ...);你将一个未初始化的FILE*传递给你的函数。稍后,您再次将其传递给quit_program(filename...。这行不通。FILE*的命名filename非常可疑,