I'm trying to develop a key value pair search tool using bsearch.
I'm not really a C programmer, I'm more used to C# but its bsearch function is *much* slower.
When I load the values into DB they display (printf) correctly.
When I do the actual comparison it doesn't return the value.
So, for debugging I'm printing the key & the value when I load it from the file. The value looks right.
In the bsearch comparison function I print the key and the value.
In this case the Key is fine but the Value looks like foreign characters. The file is in ANSI.
When I try to retrieve the value bsearch, though it found the key (and very quickly) it will not return the value.
Code:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/time.h>
#include "SLSKeyValueFinder.h"
typedef struct db {
char *sKey;
char *sValue;
int Idx;
} db_st;
char *stringDup ( const char *s ) {
char *p = malloc( strlen(s) + 1);
if ( p ) {
strcpy(p,s);
}
return p;
}
db_st parseLine ( char *line ) {
db_st result = { "","" };
{
int i=0;
char *token[2];
token[0] = NULL;
token[1] = NULL;
char *p = strchr(line,'\n');
if ( p ) *p = '\0'; // remove the \n
p = strchr(line,'\r');
if ( p ) *p = '\0'; // remove the \n
//Get Key & Value in Master list
char delims[] = "|";
char *tokResult = NULL;
tokResult = strtok( line, delims );
while( tokResult != NULL )
{
token[i] = tokResult;
tokResult = strtok( NULL, delims );
i++;
}
if(token[0] != NULL)
{
result.sKey = stringDup(token[0]);
if(token[1] != NULL && strlen(token[1]) > 0)
{
result.sValue = token[1];
}
else
{
result.sValue = "";
}
}
else
{
result.sKey = stringDup(line);
result.sValue = "";
}
}
return result;
}
db_st *readFile ( const char *filename, int *nRecords ) {
db_st *result = NULL;
int numRecords = 0;
int maxRecords = 0;
int curIdx = -1;
char buff[BUFSIZ];
FILE *fp = fopen(filename,"r");
if ( fp != NULL )
{
while ( fgets(buff, sizeof buff, fp) != NULL )
{
curIdx++;
if(strlen(buff) == 0) continue;
if ( numRecords == maxRecords )
{
int newMax = maxRecords == 0 ? 16 : maxRecords * 2;
db_st *p = realloc( result, newMax * sizeof(*p));
if ( p != NULL )
{
result = p;
maxRecords = newMax;
}
else
{
break;
}
}
db_st r = parseLine(buff);
result[numRecords].sKey = r.sKey;
result[numRecords].sValue = r.sValue;
result[numRecords].Idx = curIdx;
printf("%s %s \n", result[numRecords].sKey, result[numRecords].sValue);
numRecords++;
}
*nRecords = numRecords;
fclose(fp);
}
return result;
}
int ckValueFromKey ( const void *sKey, const void *DB ) {
const char *pKey = sKey;
const db_st *pDB = DB;
printf("%s - %s \n", pKey, pDB->sValue);
return strcmp( pKey, pDB->sKey );
}
db_st *dGlblList = NULL;
int nGlblList;
void freedb ( db_st *db, int numRecords ) {
for ( int i = 0 ; i < numRecords ; i++ ) {
db[i].Idx = 0;
free( db[i].sKey );
free( db[i].sValue );
}
free( db );
}
int sortfn ( const void *a, const void *b ) {
const db_st *pa = a;
const db_st *pb = b;
return strcmp( pa->sKey, pb->sKey );
}
int main(int argc, char *argv[])
{
static char* sRsltVal;
char *ListFilePath = "XRKeyVal.txt";
char *sKey = argv[1];
if(dGlblList == NULL)
{
dGlblList = readFile(ListFilePath, &nGlblList);
qsort( dGlblList, nGlblList, sizeof(*dGlblList), sortfn );
}
printf("Count: %d\n", nGlblList);
db_st *f = bsearch(sKey, dGlblList, nGlblList, sizeof(*dGlblList), ckValueFromKey);
if ( f )
{
sRsltVal = (*f).sValue;
printf("Value Found: %s", sRsltVal);
}
//printf("Value: %s", sRsltVal);
freedb( dGlblList, nGlblList );
dGlblList = NULL;
nGlblList = 0;
return 0;
}