gdbm programming with C

2.1k Views Asked by At

I am trying to learn gnu gdbm programming with C but can't proceed due to the paucity of the gdbm tutorial, books etc. so the only thing I have to follow is couple of simple gdbm c api codes available on w3. I wrote and compiled the following code by the help of two separate .c files but it can't fetch data from the database "testdb" so please tell me where it goes wrong. First it stores a string and, in the second part, it fetches the data. Output is; key not found.

#include <stdio.h>
#include <gdbm.h>
#include <stdlib.h>
#include <string.h>

int
main(void)
{
  GDBM_FILE dbf;
  datum key = { "testkey", 7 };     /* key, length */
  datum value = { "testvalue", 9 }; /* value, length */

  printf ("Storing key-value pair... \n");

  dbf = gdbm_open("testdb", 0, GDBM_NEWDB,0666, 0);
  gdbm_store (dbf, key, value, GDBM_INSERT);
  printf ("key: %s size: %d\n", key.dptr, key.dsize);
  gdbm_close (dbf);
  printf ("done.\n\n");

   dbf = gdbm_open("testdb", 0, GDBM_READER, 0666, 0);
   if (!dbf)
   {
      fprintf (stderr, "File %s either doesn't exist or is not a gdbm file.\n", "testdb");
      exit (1);
   }

   key.dsize = strlen("testkey") + 1;

   value = gdbm_fetch(dbf, key);

   if (value.dsize > 0) {
      printf ("%s\n", value.dptr);
      free (value.dptr);
   } 
    else {
      printf ("Key %s not found.\n", key.dptr);
   }
   gdbm_close (dbf);

   return 0;
}
1

There are 1 best solutions below

4
On

Include trailing '\0' in length.

  datum key = { "testkey", 8 };     /* key, length */
  datum value = { "testvalue", 10 }; /* value, length */

-- Edit:

Regarding the link you comment with: http://www-rohan.sdsu.edu/doc/gdbm/example.html

Read first bullet point carefully: "I'm assuming that the process which wrote the key and data included the terminating null character. …"

So; either:

datum key = { "testkey", 8 }; /* Include \0 in length */
datum value = { "testvalue", 10 };

And:

key.dsize = strlen("testkey") + 1; /* +1 for the trailing \0 */

or

datum key = { "testkey", 7 }; /* Skip \0 in length */
datum value = { "testvalue", 9 };

And:

key.dsize = strlen("testkey"); /* Do not +1 */

First version is often preferred as c-strings that's not null terminated can be a pain to work with.

Hope it helps.


-- Edit 2 (sorry, keep thinking of new things):

Also note that if you say i.e.:

datum value = { "testvalue", 5 }; /* value, length */

The value stored would be "testv".