我具有此功能,该功能应删除用户请求的配方。我总是以这种方式删除记录,但是我不知道为什么这次不能以正确的方式工作。有时它指出没有匹配项,但是会删除配方或删除文件中的所有配方,但我不明白为什么,因为我基本上创建了一个临时文件,在其中写入除用户想要的记录以外的所有记录删除,并且我使用了一个用于其他记录的函数,所以我真的不明白。那是因为所有食谱的配料长度和步骤都不一样吗?
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int stringCmpi (char *s1,char *s2);
struct _recipe
{
char name[40];
int count_i;
char ingredients[20][40];
char diff[12];
int timr;
int calories;
int count_p;
char procedure[30][500];
} recipe;
int main()
{
FILE* fbr;
FILE* temp;
char ricetta_name[] = "ricette.bin";
char temp_name[] = "temp.bin";
fbr = fopen("ricette.bin", "rb");
temp = fopen("temp.bin", "wb");
int found = 0;
char name_t[40];
int i;
char space = '\n';
if(fbr == NULL)
{
printf("Couldn't open the file.\n");
exit(1);
}
if(fbr == NULL)
{
printf("Couldn't open the file.\n");
exit(1);
}
printf("Write the name of the recipe you want to delete:\n");
fgets(name_t,sizeof(name_t),stdin);
space = getchar();
while(fread(&recipe,sizeof(recipe),1,fbr) && found == 0)
{
if(stringCmpi(name_t,recipe.name) == 0)
{
found = 1;
printf("Match found. Recipe deleted.\n");
}
else
{
fwrite(&recipe,sizeof(recipe),1,temp);
}
if(!found)
{
printf("No match.\n");
}
}
fclose(fbr);
fclose(temp);
remove(ricetta_name);
rename(temp_name,ricetta_name);
system("PAUSE");
return 0;
}
int stringCmpi (char *s1,char *s2)
{
int i=0;
for(i=0; s1[i]!='\0'; i++)
{
if( toupper(s1[i])!=toupper(s2[i]) )
return 1;
}
return 0;
}
答案 0 :(得分:1)
问题在这里:
Google Analytics
一旦找到配方,就退出循环,因此其余元素不会复制到新文件中。建议您删除while(fread(&recipe,sizeof(recipe),1,fbr) && found == 0)
子句。
此外:
&& found == 0
这实际上是在if(!found)
{
printf("No match.\n");
}
循环中,因此它将多次报告while
。请把它移到循环之外。
答案 1 :(得分:1)
正确的缩进将帮助您查看程序的实际结构。这样发布的程序具有一致的缩进效果:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int stringCmpi (char *s1,char *s2);
struct _recipe
{
char name[40];
int count_i;
char ingredients[20][40];
char diff[12];
int timr;
int calories;
int count_p;
char procedure[30][500];
} recipe;
int main()
{
FILE* fbr;
FILE* temp;
char ricetta_name[] = "ricette.bin";
char temp_name[] = "temp.bin";
fbr = fopen("ricette.bin", "rb");
temp = fopen("temp.bin", "wb");
int found = 0;
char name_t[40];
int i;
char space = '\n';
if(fbr == NULL)
{
printf("Couldn't open the file.\n");
exit(1);
}
if(fbr == NULL)
{
printf("Couldn't open the file.\n");
exit(1);
}
printf("Write the name of the recipe you want to delete:\n");
fgets(name_t,sizeof(name_t),stdin);
space = getchar();
while(fread(&recipe,sizeof(recipe),1,fbr) && found == 0)
{
if(stringCmpi(name_t,recipe.name) == 0)
{
found = 1;
printf("Match found. Recipe deleted.\n");
}
else
{
fwrite(&recipe,sizeof(recipe),1,temp);
}
if(!found)
{
printf("No match.\n");
}
}
fclose(fbr);
fclose(temp);
remove(ricetta_name);
rename(temp_name,ricetta_name);
system("PAUSE");
return 0;
}
int stringCmpi (char *s1,char *s2)
{
int i=0;
for(i=0; s1[i]!='\0'; i++)
{
if( toupper(s1[i])!=toupper(s2[i]) )
return 1;
}
return 0;
}
程序正在两次检查fbr
是否不为NULL。可能第二次检查应该是temp
。
找到要删除的配方后,程序将停止读取和复制;这意味着以下记录不会被复制。
程序抱怨找不到每种配方,直到找到所需的配方。
建议:
修改while
循环条件以消除&& ! found
,以便复制所有记录(匹配给定名称的记录除外)。
将if (! found)
的检查移到循环之外。
奖金:
stringCmpi()
在字符串s1
的末尾停止比较;这意味着“ abc”和“ abcdef”将比较相等。您可能想将return 0
更改为return s1 [i] != s2 [i]
。答案 2 :(得分:0)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct _recipe
{
char name[40];
int count_i;
char ingredients[20][40];
char diff[12];
int timr;
int calories;
int count_p;
char procedure[30][500];
} recipe;
int main(int argc, char *argv[])
{
FILE* fbr;
FILE* temp;
char *ricetta_name = "recipe.bin";
char *temp_name = "temp.bin";
int found = 0;
char name_t[40];
// Use command line arguments if possible
if (argc == 2)
{
ricetta_name = argv[1];
}
if((fbr = fopen(ricetta_name, "rb")) == NULL)
{
printf("Couldn't open the file %s.\n", ricetta_name);
exit(1);
}
if((temp = fopen(temp_name, "wb")) == NULL)
{
printf("Couldn't open the file %s.\n", temp_name);
exit(1);
}
printf("Write the name of the recipe you want to delete:\n");
fgets(name_t, sizeof(name_t), stdin);
// Remove '\n'
if (name_t[strlen(name_t) - 1] == '\n')
name_t[strlen(name_t) - 1] = 0;
while(fread(&recipe,sizeof(recipe), 1, fbr))
{
// Use standard strcasecmp()
if(strcasecmp(name_t, recipe.name) == 0)
{
found = 1;
printf("Match found. Recipe deleted.\n");
}
else
{
fwrite(&recipe, sizeof(recipe), 1, temp);
}
}
if (!found)
{
printf("No match.\n");
}
fclose(fbr);
fclose(temp);
remove(ricetta_name);
rename(temp_name,ricetta_name);
return 0;
}
请格式化您的代码:在逗号(',')后添加空格('')。并尽可能使用标准功能。