Hello I am at a lost of how to search for data in a file which was populated through structure.

Supposed I have 15 chemicals and each of them contains additional information (e.g. Chemical Name, Chemical Formula, Chemical type, State of the chemical, Antidote name etc). If I want to search for an entry under chemical type. How should I do?

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <conio.h>
#include <ctype.h>

typedef struct {
    struct {
        char name[30];
        char formulae[8];
        char type[20];
        char state[20];
        char pH[10];
        char antidote[20];
    } basic_info;

    struct {
        char supplier[50];
        char e_contact[15];
        int quantity;
        char location[6];
        char sub_loc[15];
        char expiry[11]; //format dd/mm/yyyy
    } add_info;
} database;

database chemical;

FILE *chemStore;

void Append_Database (void);
void Search_Name (void);
void Search_Suppler (void);
void Search_Type_SLoc (void);

void main()
{
    char choice;

    printf("=================\n");
    printf("Chemical Database\n");
    printf("=================\n");
    printf("1. Add new chemical.\n");
    printf("2. Search chemical via name.\n");
    printf("3. Search chemical via supplier.\n");
    printf("4. Search chemical via type & storage location.\n");
    printf("q. Exit\n");


    do {
        printf("\nEnter Choice: ");
        fflush(stdin);
        choice = getchar();
        choice=tolower(choice);

        switch (choice)
        {
        case '1': Append_Database();
            break;
        case '2': Search_Name();
            break;
        case '3': Search_Suppler();
            break;
        case '4': Search_Type_SLoc();
            break;
        case 'q': printf("\nGoodbye!");
            exit(0);
        default: printf("Invalid choice. Please repick.\n");
            break;
        }
    } while (choice != 'q');
}

void Append_Database()
{
    printf("\nRetriving Database...\n\n");
    chemStore = fopen("Chemical_Database.txt", "a");

    printf("Chemical Name: ");
    fflush(stdin);
    gets(chemical.basic_info.name);
    fprintf(chemStore, "\n%s,", chemical.basic_info.name);

    printf("Formulae: ");
    fflush(stdin);
    gets(chemical.basic_info.formulae);
    fprintf(chemStore, "%s,", chemical.basic_info.formulae);

    printf("Corrosive Level: ");
    fflush(stdin);
    gets(chemical.basic_info.type);
    fprintf(chemStore, "%s,",  chemical.basic_info.type);

    printf("State: ");
    fflush(stdin);
    gets(chemical.basic_info.state);
    fprintf(chemStore, "%s,", chemical.basic_info.state);

    printf("pH Level: ");
    fflush(stdin);
    gets(chemical.basic_info.pH);
    fprintf(chemStore, "%s,", chemical.basic_info.pH);

    printf("Antidote: ");
    fflush(stdin);
    gets(chemical.basic_info.antidote);
    fprintf(chemStore, "%s,", chemical.basic_info.antidote);

    printf("Supplier: ");
    fflush(stdin);
    gets(chemical.add_info.supplier);
    fprintf(chemStore, "%s,", chemical.add_info.supplier);

    printf("Emergency Contact No.: ");
    fflush(stdin);
    gets(chemical.add_info.e_contact);
    fprintf(chemStore, "%s,", chemical.add_info.e_contact);

    printf("Quantity: ");
    fflush(stdin);
    scanf("%d", &chemical.add_info.quantity);
    fprintf(chemStore, "%d,", chemical.add_info.quantity);

    printf("Location: ");
    fflush(stdin);
    gets(chemical.add_info.location);
    fprintf(chemStore, "%s,", chemical.add_info.location);

    printf("Sub Location: ");
    fflush(stdin);
    gets(chemical.add_info.sub_loc);
    fprintf(chemStore, "%s,", chemical.add_info.sub_loc);

    printf("Expiry Datte: ");
    fflush(stdin);
    gets(chemical.add_info.expiry);
    fprintf(chemStore, "%s,", chemical.add_info.expiry);

    fclose(chemStore);
}

Theportion above will write into Chemical_Database txt file as attached. Every field is separated by comma (.csv format).

However I am lost at how to implement search functions to search through the 'database'.

I am thinking that I have to somehow read every line in the txt file and store in a array. But how should I go about doing it with structures?

Lastly, how to search through the array?

Attachments
Hydrochloric acid,HCl,Corrosive,Liquid,Acidic,Milk of magnesia,ABC Ptd Ltd,65864123,10,Rack B,Bottom shelf,23/11/2012,
Acetonitrite,CH3CN,Non-corrosive,Liquid,Basic,Cobalt EDTA,ABC Ptd Ltd,65864123,60,Rack A,Bottom shelf,15/12/2013,
Sodium cyanide,NaCN,Non-corrosive,Solid,Basic,Cyanide Methylene Blue,YOSHI Chemical Pte Ltd,68908125,53,Rack C,Top shelf,05/01/2013,
Sulphuric acid,H2SO4,Corrosive,Liquid,Acidic,Milk of magnesia,YOSHI Chemical Pte Ltd,68908125,239,Rack A,Middle shelf,31/07/2012,
Silver nitrate,AGNO3,Non-Corrosive,Solid,Basic,,SG Industry Ptd Ltd,63931404,89,Rack D,Top shelf,09/06/2013,
Silver sulphate,AG2SO4,Non-Corrosive,Solid,Basic,,SG Inudstry Pte Ltd,63931404,50,Rack C,Bottom shelf,29/09/2013,
Mercuric Acetate,Hg(OAc)2,Non-Corrosive,Solid,Basic,,CAMEO Chemicals,60459345,100,Rack B,Middle shelf,22/08/2013,
Mercuric Chloride,HgCl2,Corrosive,Solid,Acidic,,CAMEO Chemicals,68219345,600,Rack D,Top shelf,10/20/2011,
Lead nitrate,Pb(NO3)2,Non-Corrosive,Solid,Acidic,,SG Industry Ptd Ltd,63931404,301,Rack A,Bottom shelf,09/11/2012,
Barium chloride,BaCl2,Mild-Corrosive,Solid,Basic,,ABC Ptd Ltd,65864123,60,Rack C,top shelf,15/12/2013,
Ethyl acetate,CH3COOCH2CH3,Mild-Corrosive,Liquid,Basic,Novesine,SG Industry Ptd Ltd,63931404,80,Rack B,Bottom shelf,13/02/2013,
Ethanethiol,CH3CH2SH,Corrosive,Liquid,Acidic,Oxygen,ABC Ptd Ltd,65864123,10,Rack A,Top shelf,02/02/2012,
Ammonia,NH3,Non-corrosive,Gas,Basic,Dexona,CAMEO Chemicals,68219345,600,Rack D,Top shelf,10/20/2019,
Barium hydroxide,BA(OH)2,Non-corrosive,Liquid,Basic,Calcium Gluconate,YOSHI Chemical Pte Ltd,68908125,53,Rack C,Top shelf,09/04/2015,
Arsenic Trioxide,As2O3,Corrosive,Solid,Basic,,YOSHI Chemical Pte Ltd,68908125,534,Rack B,Middle shelf,09/04/2010,

It would be a lot easier if you had written the structure all at one time as a binary file instead of one element at a time as a text file.

fwrite((char *)&chemical, 1,sizeof(database).chrmStore);

Then to read it back just change fwrite to fread

fread((char *)&chemical, 1,sizeof(database).chrmStore);

Now to search for a specific field just put that fread() line in a loop and read the file from beginning to end or until the item you want is found.

Thanks Ancient Dragon! However, I am sorry that I do not understand what you mean. Can you explain in more details?

Actually right now the main problem is that I do not know how to read from my own formatted database file and store the per chemical structure in an array with my limited knowledge of C.

If you don't want to, or can't, change the file format as I suggested then the alternative is to call fgets() to read the entire line, then call strtok() to split the line into individual tokens so that they can be stored in the structures, or used for something else. You have to be careful using strtok() because it replaces the tokens with '\0' characters, making the original string useless. So if you need the original string contents then you need to duplicate it before calling strtok() the first time. If the code below the original string isn't needed

FILE* fp = fopen("Chemical_Database.txt","r");
char line[100];

// The following will read each line of the file 
// until there are no more lines in the file
while( fget(line, sizeof(line), fp) != NULL)
{
    char* ptr = strtok(line,",");
    strcpy(chemical.basic_info.antidote, ptr);
    // repeat the next two line for each item in the line
    ptr = strtok(NULL,",");
    strcpy(chemical.basic_info.formulae, ptr);
    // etc etc
    // Now do something with the structure
}

Edited 3 Years Ago by Ancient Dragon

This article has been dead for over six months. Start a new discussion instead.