简体   繁体   中英

Binary File print key search c

Im trying to create a program that opens a binary file with a list of all the elements with their Atomic Number, Name and Symbol, in that order. The task for the program to be able to accept a name of element (should not be case sensitive) and print its atomic number and symbol

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

that code is suspicious :

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

Above in the code you do not check if fopen returns NULL or not, and here you do not check the result of fread , so you suppose there is at least NUM_ELEMENTS records in the file.

But mainly you suppose the contents of the file correspond to a sequence of how elementTag are in memory, so the file is dedicated to a given compiler with associated compiling options on a given architecture, are you sure of that ?

Your way to read is false if your file contains their external representation like

1 Hydrogen H
2 Helium He
...

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

you do not have a protection against a too long input, and you do not check the EOF case

You can do

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

The task for the program to be able to accept a name of element (should not be case sensitive)

your code uses

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

strcmp is case sensitive and you use wrong its result, use strcasecmp


In

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

because of the wrong use of strcmp you will always says you find the first element except if the input element is the first element. Using correctly the result of strcmp you will always say NOT FOUND except if the input is the first element, and stop to look at the other possibilities.

The error case must be out of the loop or knowing the end of the loop is reach, for instance :

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM