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

#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;
}

最佳答案

该代码是可疑的:


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;
     }
 }

关于c - 二进制文件打印 key 搜索c,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/55044797/

10-11 19:28
查看更多