Thread: Hash Table with Simple record in files

  1. #16
    Registered User
    Join Date
    Sep 2011
    Location
    Stockholm, Sweden
    Posts
    131
    Quote Originally Posted by itCbitC View Post
    Exactly my point.

    Why would someone ftp the binary output to another system and read it there when the right thing is to move source code and ascii input files, and re-compiling; unless someone isn't well versed with block I/O.
    I was thinking ascii and binary files would not be used at the same time, but rather one format would be chosen over the other. I was simply trying to raise the issue of portability as a possible issue :-)

  2. #17
    Registered User
    Join Date
    Oct 2008
    Location
    TX
    Posts
    2,059
    @iceaway:
    No worries! we are on the same page on that.
    Last edited by itCbitC; 10-04-2011 at 11:21 AM.

  3. #18
    Registered User
    Join Date
    Oct 2011
    Location
    India
    Posts
    53
    Hii....In the above program Record number, number value & name are saved in that random.dat file. Now i learn to how to change the number value and name. Now my question is if i want to list out all names those are saved in that file, How can i list out ?? and another question . This is searched by record number. If i want to search by name means, How can i do this??

  4. #19
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    Quote Originally Posted by infantheartlyje View Post
    Now my question is if i want to list out all names those are saved in that file, How can i list out ??
    Break the job down into simple steps. If I handed you a piece of paper where each line had a name and address, and I told you to read them all to me, how would you do it?
    Quote Originally Posted by infantheartlyje View Post
    This is searched by record number. If i want to search by name means, How can i do this??
    Swap out number for name for whatever you are doing.


    Quzah.
    Hope is the first step on the road to disappointment.

  5. #20
    Registered User
    Join Date
    Oct 2011
    Location
    India
    Posts
    53
    Quote Originally Posted by quzah View Post
    Break the job down into simple steps. If I handed you a piece of paper where each line had a name and address, and I told you to read them all to me, how would you do it?


    Quzah.
    I read one by one . Its okie. In the above program how can i list out ? Its all in random order na ?? It has two fields okie.. But now suppose am having 10 fields. Now i want to list out the specific field ? How can i do this in the above program ? And if i want to retrieve the field of particular date(its also one field) (Example list out the client names whose are given the dividend amount at 01Jun11) . How can i retrieve the names ?

  6. #21
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    Quote Originally Posted by infantheartlyje View Post
    I read one by one . Its okie. In the above program how can i list out ? Its all in random order na ??
    Does it matter if it's in random order? You didn't say you wanted to print it all in order. Start at the beginning of the file, read one record, display it. Repeat reading and displaying until done.
    Quote Originally Posted by infantheartlyje View Post
    It has two fields okie.. But now suppose am having 10 fields. Now i want to list out the specific field ? How can i do this in the above program ? And if i want to retrieve the field of particular date(its also one field) (Example list out the client names whose are given the dividend amount at 01Jun11) . How can i retrieve the names ?
    You need to make a function that will operate on a given field. For example:
    Code:
    struct thing
    {
        ...
        char letter;
        ...
    };
    We have a thing with an undetermined number of fields, and we know one of them is 'letter'. So if we want to find all of an item, or even one, based off of 'letter', we would maybe make a function to 'findbyletter':
    Code:
    type findbyletter( ... )
    {
        ...
    }
    Now you simply decide what arguments you need to search, and what you want to return. For example, if all we had was an array of these things, we could simply loop through them:
    Code:
    int findbyletter( struct thing ourthings[], int howmany, int letter )
    {
        /* return the index of the first thing with 'letter' */
        int x;
        for( x = 0; x < howmany; x++ )
            if( ourthings[ x ].letter == letter )
                return x;
        return -1; /* error, not found */
    }
    The same concept applies. If you can find any one thing in your file, list, data, then you can find any other thing by doing the exact same thing for a different field. (For example, if there was another value in thing that was 'number', I could swap out 'letter' for 'number' and return that field's index the same way with a fairly simple rewrite.


    Quzah.
    Hope is the first step on the road to disappointment.

  7. #22
    Registered User
    Join Date
    Oct 2011
    Location
    India
    Posts
    53
    In the below coding how can i do this?
    Code:
    //random access file demo 
    #include <stdlib.h> 
    #include <stdio.h> 
    #include <time.h> 
    #include <ctype.h> 
    #include <string.h> 
     #define FNAME "random.dat" 
     // test data struct 
    struct t_Record   
    {
             int randnum;     char word[16]; 
    }   Record;  
    
    
      /////////////////////////////////////////////////////// // Random Access File Handlers 
    // 
     // open or create the file 
    FILE *FileOpen(char* Filename) 
      {
              FILE* pFile;   
              pFile = fopen(Filename,"rb+");   
               if (!pFile)   
                   pFile = fopen(Filename,"wb+");    
               return pFile;
      }  
     // Write a record to the file 
    int WriteRecord(FILE *File, int RecNum)  
     { 
            if( fseek(File, RecNum * sizeof(Record), SEEK_SET) == 0 )             
        if ( fwrite(&Record,sizeof(Record),1,File) )         
                               return 1;   
                 return 0; 
    } 
      // read a record from the file
     int ReadRecord(FILE *File, int RecNum)  
     { 
            if( fseek(File, RecNum * sizeof(Record), SEEK_SET) == 0 )               
       if ( fread(&Record,sizeof(Record),1,File) )    
             return 1;  
       return 0; 
    } 
       ////////////////////////////////////////////////////////
     // this is for demonstration purposes only
     // you would not do this in a real program 
    void InitFile(FILE* File) 
     {
          int x, y;    
         memset(&Record,sizeof(Record),0);  
         for (x = 0; x < 1000; x++)      
         { 
                  Record.randnum = rand();        
                  for (y = 0; y < ((Record.randnum % 15) + 1); y++)         
                            Record.word[y] = (rand() % 26) + 'a';     
                  Record.word[y] = 0;      
                   if (! WriteRecord(File,x))       
                             printf("Oh drat!");  
        }
     }    
      ////////////////////////////////////////////////////////// // program mains //
     int main (void)  
     { 
                   FILE *File;   
                   int Quit = 0;    
                    int Rec = 0; // record number     
                   srand(time(NULL));     
                    File = FileOpen(FNAME); 
                     if (!File)     
                   { 
                           printf("Curses foiled again!\n\n");  
                           exit(-1); 
                    }     
                  // write out 1000 test records    
                  printf("Create a new file? (y/n)  ");   
                  if ( toupper( getchar() ) == 'Y')     
                         InitFile(File);     
                  // lets peek    
                  do       
                 {
                         printf("Enter a record number (0 - 999) to load : ");       
                         if (! scanf("%d",&Rec) )     
                              Quit = 1;  
                         // enter any letter to quit     
                         else           
                         { // read and display the record          
                                 if (! ReadRecord(File,Rec) )             
                                     printf("Could not read record %d\n",Rec);       
                                else          
                                  { 
                                           printf("-----\n");           
                                           printf("Record Number : %d\n",Rec);           
                                           printf("Number Value  : %d\n",Record.randnum);               
                                            printf("Record Name   : %s\n",Record.word);             
                                           printf("-----\n");           
                                          getchar();             
                                          printf("Do you want to rename this record (y/n)? ");         
                                          if ( toupper( getchar() ) == 'Y')        
                                         {
                                               printf("Enter a new name : ");           
                                                if ( scanf("%s",Record.word) )                   
                                                WriteRecord(File,Rec); 
                                          }
                                  }
                           }   
                   } while (! Quit);       
                  fclose(File);   
                  return 0; 
    }
    In the above example , how can i solve my problem.
    if i know record number field means, i can get the record of the record number. But how can i get the all record number in the below program ???? The record number is auto generated na ? how can i get the record numbers ? now?
    Last edited by infantheartlyje; 10-06-2011 at 02:02 AM.

  8. #23
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    Please edit that and add appropriate newlines.


    Quzah.
    Hope is the first step on the road to disappointment.

  9. #24
    Registered User
    Join Date
    Oct 2011
    Location
    India
    Posts
    53
    if i know record number field means, i can get the record of the record number. But how can i get the all record number in the below program ???? The record number is auto generated na ? how can i get the record numbers ? now?

  10. #25
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    If you have saved the record number some place, you can just check that field when you are reading the file back. Pretty much the same way you would check any other field.


    Quzah.
    Hope is the first step on the road to disappointment.

  11. #26
    Banned
    Join Date
    Aug 2010
    Location
    Ontario Canada
    Posts
    9,547
    You do these things by writing index files...

    Picture this... you have an inventory database of 100,000 items...WOW! that's a lot of stuff... 100,000 records...

    Now you need to index the stuff which may or may not be in any sensible order (the only sure order is record numbers)... So you build a file to extract your data... and sort the smaller file...

    Lets say you want to index by name... build a struct like this...
    Code:
    struct t_Names_idx
      { char name[100];
         int record; }
       Names_idx;
    Now you go through your big honking inventory file and extract all the names and record numbers ... eg: Record 10 name = "100K Resistor 1/4 watt".... copy the name to your new struct, assign the record number, and write it to a new file... "names.idx".

    This produces a much smaller file that is easily read into memory, sorted as a simple array, then written out again.

    Now you have a file in name order... you use a binary search algorythm (Google is your friend) which is lightning fast on records based files... you find the name, this gives you the record number from the main file... so you load that record from the main file.

    Need a secondary search by Supplier? Just make another .idx file...

    It sounds complex... but it really isn't. The hardest part is sorting the .idx file.
    Last edited by CommonTater; 10-06-2011 at 05:45 AM.

  12. #27
    Banned
    Join Date
    Aug 2010
    Location
    Ontario Canada
    Posts
    9,547
    Quote Originally Posted by quzah View Post
    If you have saved the record number some place, you can just check that field when you are reading the file back. Pretty much the same way you would check any other field.


    Quzah.
    Note that in my sample code I showed one way... ask the user... the OP needs to study how the records are written and read from the file to understand. The record number and record size tell it where to seek... He doesn't have to "get the record number" he just needs to know which record is currently loaded. (This is the Rec variable in my example.)

    Also note that *at no time* should it ever be necessary to load more than one record at a time.

    Finally ... record numbers run just like array indexes... they start at 0 and go to however many are in the file...
    Last edited by CommonTater; 10-06-2011 at 06:00 AM.

  13. #28
    Registered User
    Join Date
    Oct 2011
    Location
    India
    Posts
    53
    Hi CommonTater,
    Here i did some code. I can write the records the index and my data file. But i can't retrieve it. Below here i have given my code. Kindly please check my code and correct it. I am not sure if the record are stored correctly or not .
    Code:
    #include <stdlib.h>
    #include <stdio.h>
    #include <time.h>
    #include <ctype.h>
    #include <string.h>
    
    #define DBNAME "datatb.txt"
    #define INXNAME "index.txt"
    char *srordes;
    // test data struct
    struct t_Record
      { 
        int randnum;
        char *S_trancode;
        char *S_sectype;
        char *S_secsym;
        char *D_tdate;
        char *D_sdate;
        int N_quantity;
        int N_trdamt;
        char *S_sourcetype;
        char *S_sourcesym;
    }Record;
    
    
    void getclientvalues()
    {
        Record.S_trancode = (char * ) malloc( 2);
        Record.S_sectype =(char * ) malloc( 4);
        Record.S_secsym =(char * ) malloc( 5);
        Record.D_tdate = (char * ) malloc( 8);
        Record.D_sdate =(char * ) malloc( 8);
        Record.S_sourcetype =(char * ) malloc( 4);
        Record.S_sourcesym =(char * ) malloc( 5);
        printf("Enter Transacation Code : ");
        scanf("%s",Record.S_trancode);
        printf("Enter Security Type Code : ");
        scanf("%s",Record.S_sectype);
        printf("Enter Security Symbol : ");
        scanf("%s",Record.S_secsym);
        printf("Enter Trade Date : ");
        scanf("%s",Record.D_tdate);
        printf("Enter Settle Date : ");
        scanf("%s",Record.D_sdate);
        printf("Enter Quantity : ");
        scanf("%d",&Record.N_quantity);
        printf("Enter Trade Amount : ");
        scanf("%d",&Record.N_trdamt);
        //getsrcortype();
        printf("Enter Source/Destination Type ");
        scanf("%s",Record.S_sourcetype);
        printf("Enter Source/Destination Symbol ");
        scanf("%s",Record.S_sourcesym);
    }
    void printclientvalues()
    {
    
        printf("Transacation Code\tSecurity Type Code\tSecurity Symbol\tTrade Date\tSettle Date\tQuantity\tTrade Amount\tSource  Type\tSource Symbol \n);
        printf("%s\t\t",Record.S_trancode);
        printf("%s\t\t",Record.S_sectype);
        printf("%s\t\t",Record.S_secsym);
        printf("%s\t",Record.D_tdate);
        printf("%s\t",Record.D_sdate);
        printf("%d\t",Record.N_quantity);
        printf("%d\t",Record.N_trdamt);
        printf("%s\t",Record.S_sourcetype);
        printf("%s\t\n",Record.S_sourcesym);
    }
    int WriteRecord(FILE *dtFile, FILE *inxFile, int RecNum)
      {
        if( fseek(dtFile, RecNum * sizeof(Record), SEEK_SET) == 0 )
        {
             if ( fwrite(&Record,sizeof(Record),1,dtFile) )
                {
                    fwrite(&RecNum,sizeof(int),1,inxFile);
                    return 1;
                }
        }
        return 0;
     }
    
    int ReadRecord(FILE* dtFile,FILE* inxFile)
      {
        int RecNum;
        while(fread(&RecNum,sizeof(int),1,inxFile))
        {
            if( fseek(dtFile, RecNum * sizeof(Record), SEEK_SET) == 0 )
                 if ( fread(&Record,sizeof(Record),1,dtFile) )
                {
                    printclientvalues();
                }
    
        }
        return 0;
     }
    void InitFile(FILE* File,FILE* inxFile)
     { 
        int x, y;
           memset(&Record,sizeof(Record),0);
            if (! WriteRecord(File,inxFile,x))
              printf("Oh drat!");   
    }
    
    int main (void)
    {
        FILE *dtFile;
        FILE *inFile;
        //int Quit = 0;
               int Rec = 0; // record number
    
        srand(time(NULL));
    
        // File = FileOpen(FNAME);
         dtFile=fopen(DBNAME,"w+");
         inFile=fopen(INXNAME,"a+");
        /*if (!dtFile)
        {
            printf("Curses foiled again!\n\n");
            exit(-1);
        }*/
        printf(" \nTo add a Record press  A : ");
        printf(" \nTo View a Record press B : \n");
        switch( toupper(getchar()))
        {
            case 'A' :
                    InitFile(dtFile,inFile);
                    genrandnum();
                    getclientvalues();
                    printf("Enter Record Number : ");scanf("%d",&Rec);
                    WriteRecord(dtFile,inFile,Rec);
                    break;
            case 'B' :
                    ReadRecord(dtFile,inFile);
                    printclientvalues();
                    break;
    
            default : printf("Wrong Selection");
        }
        return 0;
    }
    Please correct my code to store and retrieve data.
    Last edited by infantheartlyje; 10-07-2011 at 01:13 AM.

  14. #29
    Banned
    Join Date
    Aug 2010
    Location
    Ontario Canada
    Posts
    9,547
    Code:
    // test data struct
    struct t_Record
      { 
        int randnum;
        char *S_trancode;
        char *S_sectype;
        char *S_secsym;
        char *D_tdate;
        char *D_sdate;
        int N_quantity;
        int N_trdamt;
        char *S_sourcetype;
        char *S_sourcesym;
    }Record;
    If this is what you intend to write to the disk, you are in trouble from the get-go... What you will be saving is record after record of invalid pointers to data that no longer exists.

    The actual data has to be IN the record itself... Don't use char *variable... that's linked list crap... use char variable[size]; and have your users enter data directly into the struct itself...

    Code:
    // test data struct
    struct t_Record
      { 
        int randnum;
        char S_trancode[3];
        char S_sectype[4];
        char S_secsym[5];
        char D_tdate[8];
        char D_sdate[8];
        int N_quantity;
        int N_trdamt;
        char S_sourcetype[4]
        char S_sourcesym[5]
    }Record;
    Data entry now looks like this...

    Code:
    void getclientvalues()
    {
        printf("Enter Transacation Code : ");
        scanf("%2s",Record.S_trancode);
        printf("Enter Security Type Code : ");
        scanf("%3s",Record.S_sectype);
        printf("Enter Security Symbol : ");
        scanf("%4s",Record.S_secsym);
        printf("Enter Trade Date : ");
        scanf("%7s",Record.D_tdate);
        printf("Enter Settle Date : ");
        scanf("%7s",Record.D_sdate);
        printf("Enter Quantity : ");
        scanf("%d",&Record.N_quantity);
        printf("Enter Trade Amount : ");
        scanf("%d",&Record.N_trdamt);
        //getsrcortype();
        printf("Enter Source/Destination Type ");
        scanf("%3s",Record.S_sourcetype);
        printf("Enter Source/Destination Symbol ");
        scanf("%4s",Record.S_sourcesym);
    }
    Note that I've added field sizes to the scanf() calls... this is to prevent array bounds overflows during data entry.


    You don't need to initialize a new record into the file ... just seek to the end of the file and write it.

    Your index file is useless as it's just a bunch of ints written to the file with no other information. All you're building is an in order list of record numbers... you can do that by simple math. For an index file to be useful you need to index *something*. So this is a record based random access file as well.

    For example you could index the random numbers (why is that in there anyway???)
    Code:
    struct t_rnumidx
      { int randnum;
        int record; }
      rnumidx;
    So each time you write a new record to your disk, you write a new record to your index containing the random number and the record number...
    Now you have to SORT this file so that the random numbers are in order. It is then used as a lookup device where a user would enter the random number from the keyboard, a binary search of the sorted index file finds the number.... you can then fetch the main data record from the larger file using the record number in the index struct.

    And, you really should not name these files *.txt ... they are NOT text files and you cannot view or change them in a text editor. The usual suffixes for this type of file are *.dat and *.idx ...

  15. #30
    Banned
    Join Date
    Aug 2010
    Location
    Ontario Canada
    Posts
    9,547
    Quote Originally Posted by infantheartlyje View Post
    if i know record number field means, i can get the record of the record number. But how can i get the all record number in the below program ???? The record number is auto generated na ? how can i get the record numbers ? now?
    The layout is exactly an array of structs, but on disk instead of memory...

    Nothing is in random order... it's in the order you wrote it.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. more serious hash table
    By Aisthesis in forum C++ Programming
    Replies: 9
    Last Post: 09-22-2010, 11:06 PM
  2. Hash Table
    By mrsirpoopsalot in forum C++ Programming
    Replies: 11
    Last Post: 11-14-2009, 09:10 PM
  3. hash table
    By mexx in forum C++ Programming
    Replies: 0
    Last Post: 06-30-2009, 12:23 PM
  4. Hash Table
    By Cpro in forum C++ Programming
    Replies: 3
    Last Post: 03-20-2008, 02:14 PM
  5. Errors in a simple hash table class.
    By TheSquid in forum C++ Programming
    Replies: 4
    Last Post: 02-23-2005, 04:49 AM

Tags for this Thread