@iceaway:
No worries! we are on the same page on that.
Last edited by itCbitC; 10-04-2011 at 11:21 AM.
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??
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?Swap out number for name for whatever you are doing.
Quzah.
Hope is the first step on the road to disappointment.
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 ?
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.You need to make a function that will operate on a given field. For example: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:struct thing { ... char letter; ... };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:type findbyletter( ... ) { ... }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.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 */ }
Quzah.
Hope is the first step on the road to disappointment.
In the below coding how can i do this?
In the above example , how can i solve my problem.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; }
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.
Please edit that and add appropriate newlines.
Quzah.
Hope is the first step on the road to disappointment.
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?
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.
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...
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".Code:struct t_Names_idx { char name[100]; int record; } 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.
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.
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 .
Please correct my code to store and retrieve data.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; }
Last edited by infantheartlyje; 10-07-2011 at 01:13 AM.
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.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;
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...
Data entry now looks like this...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;
Note that I've added field sizes to the scanf() calls... this is to prevent array bounds overflows during data entry.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); }
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???)
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...Code:struct t_rnumidx { int randnum; int record; } rnumidx;
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 ...