二进制文件打印密钥搜索c

时间:2019-03-07 13:19:10

标签: c file

我试图创建一个程序来打开一个二进制文件,该文件包含按顺序排列的所有元素及其原子序号,名称和符号的列表。该程序的任务是能够接受元素名称(不区分大小写)并打印其原子序号和符号

#include <stdio.h>
#include <string.h>

    #include "elements.h"

#define NUM_ELEMENTS (118)

struct elementTag {
   int AtomicNumber;
   char Name[31];
   char Symbol[4];  // note: the longest Symbol has 3 characters
};

typedef struct elementTag ElementType;
    int
    main()
    {
        struct elementTag elements[NUM_ELEMENTS];

    int ctr;
    char ele[31];

    FILE *fbin;

    fbin = fopen ("ELEMENTS.bin", "rb");

    for ( ctr = 0; ctr < NUM_ELEMENTS; ctr ++)
    {
        fread (&elements[ctr], sizeof(struct elementTag), 1, fbin);
    }

    printf("\nInput element name to search: ");
    scanf("%s", ele);

    for ( ctr = 0; ctr < NUM_ELEMENTS; ctr ++)
    {
        if (strcmp(ele, elements[ctr].Name))
        {
            printf("Atomic Number: %d, Symbol: %s\n\n", elements[ctr].AtomicNumber, elements[ctr].Symbol);
        }
        else
        {
            printf("NOT FOUND!\n\n");
            break;
        }
    }

    fclose (fbin);

    return 0;
}

1 个答案:

答案 0 :(得分:0)

该代码可疑:

for ( ctr = 0; ctr < NUM_ELEMENTS; ctr ++)
{
    fread (&elements[ctr], sizeof(struct elementTag), 1, fbin);
}

在代码上方,您不检查 fopen 是否返回NULL,并且在这里您不检查 fread 的结果,因此您假设至少存在NUM_ELEMENTS记录在文件中。

但是主要是假设文件的内容与 elementTag 在内存中的顺序相对应,因此该文件专用于给定的编译器,并具有给定体系结构上的相关编译选项。确定吗?

如果文件包含外部表示形式,则您的读取方式为false

1 Hydrogen H
2 Helium He
...

char ele[31];
...
scanf("%s", ele);

您没有防止输入时间过长的保护措施,也没有检查EOF情况

你可以

if (scanf("%30s", ele) == 1) {
  for (...

  

程序能够接受元素名称的任务(不应区分大小写)

您的代码使用

if (strcmp(ele, elements[ctr].Name))

strcmp 区分大小写,并且您使用了错误的结果,请使用 strcasecmp


for ( ctr = 0; ctr < NUM_ELEMENTS; ctr ++)
{
    if (strcmp(ele, elements[ctr].Name))
    {
        printf("Atomic Number: %d, Symbol: %s\n\n", elements[ctr].AtomicNumber, elements[ctr].Symbol);
    }
    else
    {
        printf("NOT FOUND!\n\n");
        break;
    }
}

由于 strcmp 的错误使用,您总是会说找到第一个元素,除非输入元素是第一个元素。正确使用 strcmp 的结果,您将总是说NOT FOUND,除非输入是第一个元素,然后停下来看看其他可能性。

错误情况必须在循环之外,或者知道循环的终点已经到达,例如:

 for ( ctr = 0; ; ctr ++)
 {
     if (ctr == NUM_ELEMENTS)
     {
         printf("NOT FOUND!\n\n");
         break;
     }

     if (!strcasecmp(ele, elements[ctr].Name))
     {
         printf("Atomic Number: %d, Symbol: %s\n\n", elements[ctr].AtomicNumber, elements[ctr].Symbol);
          break;
     }
 }