Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/68.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
My delete函数删除struct的错误记录_C_Struct_Binaryfiles - Fatal编程技术网

My delete函数删除struct的错误记录

My delete函数删除struct的错误记录,c,struct,binaryfiles,C,Struct,Binaryfiles,我有这个功能,应该删除用户要求的配方。我总是以这种方式删除记录,但我不知道为什么这次它不能以正确的方式工作。有时它会说没有匹配项,但它会删除配方或删除文件中的所有配方,我不明白为什么,因为我基本上创建了一个临时文件,在该文件中写入除用户想要删除的记录之外的所有记录,并且我使用了一个用于另一条记录的函数,所以我真的不明白。这是不是因为所有配方的配料长度和程序都不一样 #include <stdio.h> #include <stdlib.h> #include <st

我有这个功能,应该删除用户要求的配方。我总是以这种方式删除记录,但我不知道为什么这次它不能以正确的方式工作。有时它会说没有匹配项,但它会删除配方或删除文件中的所有配方,我不明白为什么,因为我基本上创建了一个临时文件,在该文件中写入除用户想要删除的记录之外的所有记录,并且我使用了一个用于另一条记录的函数,所以我真的不明白。这是不是因为所有配方的配料长度和程序都不一样

#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;
}
#包括
#包括
#包括
int stringCmpi(字符*s1,字符*s2);
结构配方
{
字符名[40];
int count_i;
煤焦成分[20][40];
char-diff[12];
int-timr;
热量;
整数计数;
char程序[30][500];
}配方;
int main()
{
文件*fbr;
文件*temp;
char ricetta_name[]=“ricette.bin”;
char temp_name[]=“临时箱”;
fbr=fopen(“ricette.bin”、“rb”);
温度=fopen(“温度箱”、“wb”);
int=0;
字符名称_t[40];
int i;
字符空间='\n';
如果(fbr==NULL)
{
printf(“无法打开文件。\n”);
出口(1);
}
如果(fbr==NULL)
{
printf(“无法打开文件。\n”);
出口(1);
}
printf(“写下要删除的配方名称:\n”);
fgets(名称、尺寸、标准尺寸);
space=getchar();
而(fread(&recipe,sizeof(recipe),1,fbr)和&found==0)
{   
if(stringCmpi(name\u t,recipe.name)==0)
{
发现=1;
printf(“找到匹配项。配方已删除。\n”);
}
其他的
{
fwrite(和配方),sizeof(配方),1,temp;
}
如果(!找到)
{
printf(“不匹配。\n”);
}
}
fclose(fbr);
fclose(temp);
删除(ricetta_名称);
重命名(临时名称、ricetta名称);
系统(“暂停”);
返回0;
}
int stringCmpi(字符*s1,字符*s2)
{
int i=0;
对于(i=0;s1[i]!='\0';i++)
{
if(toupper(s1[i])!=toupper(s2[i]))
返回1;
}
返回0;
}
问题在于:

while(fread(&recipe,sizeof(recipe),1,fbr) && found == 0)
找到配方后,退出循环,因此剩余元素不会复制到新文件中。我建议您删除
&&found==0
子句

此外:

if(!found)
{
    printf("No match.\n");
}
这实际上在
while
循环中,因此它会多次报告
不匹配。请将其移出循环。

问题在于:

while(fread(&recipe,sizeof(recipe),1,fbr) && found == 0)
找到配方后,退出循环,因此剩余元素不会复制到新文件中。我建议您删除
&&found==0
子句

此外:

if(!found)
{
    printf("No match.\n");
}
这实际上在
while
循环中,因此它会多次报告
不匹配。请把它移到圈外

  • 适当的缩进将帮助您查看程序的实际结构。这是发布的程序在一致缩进下的外观:

    #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;
    }
    
    #包括
    #包括
    #包括
    int stringCmpi(字符*s1,字符*s2);
    结构配方
    {
    字符名[40];
    int count_i;
    煤焦成分[20][40];
    char-diff[12];
    int-timr;
    热量;
    整数计数;
    char程序[30][500];
    }配方;
    int main()
    {
    文件*fbr;
    文件*temp;
    char ricetta_name[]=“ricette.bin”;
    char temp_name[]=“临时箱”;
    fbr=fopen(“ricette.bin”、“rb”);
    温度=fopen(“温度箱”、“wb”);
    int=0;
    字符名称_t[40];
    int i;
    字符空间='\n';
    如果(fbr==NULL)
    {
    printf(“无法打开文件。\n”);
    出口(1);
    }
    如果(fbr==NULL)
    {
    printf(“无法打开文件。\n”);
    出口(1);
    }
    printf(“写下要删除的配方名称:\n”);
    fgets(名称、尺寸、标准尺寸);
    space=getchar();
    而(fread(&recipe,sizeof(recipe),1,fbr)和&found==0)
    {
    if(stringCmpi(name\u t,recipe.name)==0)
    {
    发现=1;
    printf(“找到匹配项。配方已删除。\n”);
    }
    其他的
    {
    fwrite(和配方),sizeof(配方),1,temp;
    }
    如果(!找到)
    {
    printf(“不匹配。\n”);
    }
    }
    fclose(fbr);
    fclose(temp);
    删除(ricetta_名称);
    重命名(临时名称、ricetta名称);
    系统(“暂停”);
    返回0;
    }
    int stringCmpi(字符*s1,字符*s2)
    {
    int i=0;
    对于(i=0;s1[i]!='\0';i++)
    {
    if(toupper(s1[i])!=toupper(s2[i]))
    返回1;
    }
    返回0;
    }
    
  • 程序两次检查
    fbr
    是否不为空。第二个检查可能是针对
    temp

  • 当发现要删除的配方时,程序停止读取和复制;这意味着不会复制以下记录

  • 程序抱怨在找到所需配方之前,没有找到每个配方的配方

  • 建议:

    • 修改
      ,同时
      循环条件消除
      &&!找到
      ,以便复制除与给定名称匹配的记录之外的所有记录

    • 如果(!found)
    在循环外,则将检查移动到

    奖金:

    • 函数
      stringCmpi()
      在字符串
      s1
      末尾停止比较;这意味着“abc”和“abcdef”将相等。您可能需要将
      返回0
      更改为
      返回s1[i]!=s2[i]
  • 适当的缩进将帮助您查看程序的实际结构。这是发布的程序在一致缩进下的外观:

    #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;
    }
    
    #包括
    #包括
    #包括
    int stringCmpi(字符*s1,字符*s2);
    结构配方
    {
    字符名[40];
    int count_i;
    煤焦成分[20][40];
    char-diff[12];
    int-timr;
    热量;
    整数计数;
    字符处理