Solved

Using the ndbm library

Posted on 1997-05-19
7
195 Views
Last Modified: 2013-12-26
Does anyone have any experience using the old ndbm library in UNIX?  I have a structure defined something like:
      char key[12];
      typedef struct {
            char name[50];
            char addr[50];
            char phone[12];
      } data;
How do I store and retrieve the data?  I've only used the library for singular strings.

Quick replies will be greatly appreciated.
0
Comment
Question by:walkerm
  • 4
  • 3
7 Comments
 
LVL 3

Accepted Solution

by:
dhm earned 100 total points
ID: 1292903
ndbm uses a structure called a datum to describe both keys and values.  The structure looks like this:

struct datum {
    char *dptr;
    int   dlen;
} ;

When you work with strings, you usually set dptr to point to the string, and dlen is strlen(dptr).  In this case, however, you just set dptr to point to your data structure, and dlen will be sizeof(data).  (Assuming the typedef you gave in the question.  The sizeof will probably be 112.)

So, here's some sample code:

DBM *database = dbm_open( /* filename, flags, etc */ );

char key[12];
data my_data;
datum K;
datum V;

memset( key, 0, sizeof(key) );
memset( &my_data, 0, sizeof(my_data) );

strcpy( key, "billgates" );
strcpy( my_data.name, "Bill Gates" );
strcpy( my_data.addr, "Redmond, WA" );
strcpy( my_data.phone, "800-WINDOZE" );

K.dptr = key;
K.dlen = strlen(key);
V.dptr = (char *)(&my_data);
V.dlen = sizeof(my_data);

db_store( database, K, V, DBM_REPLACE );


0
 

Author Comment

by:walkerm
ID: 1292904
Thanks. Now I need to use dbm_fetch to retrieve the data (assuming the same structure).

Thanks again
0
 

Author Comment

by:walkerm
ID: 1292905
Thanks. Now I need to use dbm_fetch to retrieve the data (assuming the same structure).  Please help

Thanks again
0
Free Tool: ZipGrep

ZipGrep is a utility that can list and search zip (.war, .ear, .jar, etc) archives for text patterns, without the need to extract the archive's contents.

One of a set of tools we're offering as a way to say thank you for being a part of the community.

 
LVL 3

Expert Comment

by:dhm
ID: 1292906
Continuing from the db_store() in my example:

V = db_fetch( database, K );

if (V.dptr == 0) { printf( "Not found!\n" ); exit( 0 ); }
if (V.dlen != sizeof(my_data)) { printf( "Wrong data size!\n"; }
memcpy( &my_data, V.dptr, sizeof(my_data) );

printf( "Phone number for %s is %s\n", my_data.name, my_data.phone );
0
 

Author Comment

by:walkerm
ID: 1292907
I'm getting a segmentation fault on the call to dbm_fetch. I have Digital UNIX V4.0B  (Rev. 564).

Any ideas?
0
 
LVL 3

Expert Comment

by:dhm
ID: 1292908
Here's a complete, working program that I compiled on Digital Unix 4.0, using both gcc-2.7.2 and the DEC C compiler.

#include <stdio.h>
#include <malloc.h>
#include <string.h>
#include <ndbm.h>
#include <errno.h>
#include <fcntl.h>

typedef struct data {
  char       name[50];
  char       addr[50];
  char       phone[12];
} data;

int
main( int argc, char **argv )
{
  DBM      *database;
  datum       K;
  datum       V;
  char       key[12];
  data       my_data;
  int       result;

  database = dbm_open( "/tmp/test-db", O_RDWR | O_CREAT, 0666 );
  if (database == 0) {
    printf( "Can't open/create database: %d\n", errno );
    exit( errno );
  }

  strcpy( key, "billgates" );
  strcpy( my_data.name, "Bill Gates" );
  strcpy( my_data.addr, "Redmond, WA" );
  strcpy( my_data.phone, "800-WINDOZE" );

  K.dptr = key;
  K.dsize = strlen( key );
  V.dptr = &my_data;
  V.dsize = sizeof(my_data);

  result = dbm_store( database, K, V, DBM_REPLACE );
  printf( "dbm_store result = %d\n", result );

  V.dptr = 0;
  V.dsize = 0;
  V = dbm_fetch( database, K );

  if (V.dptr == 0) {
    printf( "I can't find the key I just inserted!\n" );
  } else {
    if (V.dsize != sizeof(my_data)) {
      printf( "Expected the value for this key to be %d bytes long, not %d\n",
            sizeof(my_data), V.dsize );
    } else {
      memcpy( &my_data, V.dptr, sizeof(my_data) );
      printf( "Name: %s Address %s Phone %s\n",
            my_data.name, my_data.addr, my_data.phone );
    }
  }

  printf( "Now, look for username \"marca\" (expect NOT FOUND)\n" );

  strcpy( key, "marca" );
  K.dptr = key;
  K.dsize = strlen( key );

  V.dptr = 0;
  V.dsize = 0;
  V = dbm_fetch( database, K );

  if (V.dptr == 0) {
    printf( "I can't find the key. (That's good!)\n" );
  } else {
    if (V.dsize != sizeof(my_data)) {
      printf( "Expected the value for this key to be %d bytes long, not %d\n",
            sizeof(my_data), V.dsize );
    } else {
      memcpy( &my_data, V.dptr, sizeof(my_data) );
      printf( "Name: %s Address %s Phone %s\n",
            my_data.name, my_data.addr, my_data.phone );
    }
  }

  dbm_close( database );

  exit( 0 );
}

0
 

Author Comment

by:walkerm
ID: 1292909
Thank you!!!  That really help me out.
0

Featured Post

Announcing the Most Valuable Experts of 2016

MVEs are more concerned with the satisfaction of those they help than with the considerable points they can earn. They are the types of people you feel privileged to call colleagues. Join us in honoring this amazing group of Experts.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
Adapt this command to show who installed 29 111
Add content to output file 4 67
windows 10 how make picture as desktop background 2 65
wordcount challenge 11 134
Exception Handling is in the core of any application that is able to dignify its name. In this article, I'll guide you through the process of writing a DRY (Don't Repeat Yourself) Exception Handling mechanism, using Aspect Oriented Programming.
Have you tried to learn about Unicode, UTF-8, and multibyte text encoding and all the articles are just too "academic" or too technical? This article aims to make the whole topic easy for just about anyone to understand.
This video will show you how to get GIT to work in Eclipse.   It will walk you through how to install the EGit plugin in eclipse and how to checkout an existing repository.
Two types of users will appreciate AOMEI Backupper Pro: 1 - Those with PCIe drives (and haven't found cloning software that works on them). 2 - Those who want a fast clone of their boot drive (no re-boots needed) and it can clone your drive wh…

820 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question