⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 rolodeck.cpp

📁 CBASE v1.01 采用Borland公司TC++编写的数据库管理源程序库
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/*	Copyright (c) 1989 Citadel	*/
/*	   All Rights Reserved    	*/

/* #ident	"@(#)rolodeck.c	1.4 - 90/06/21" */

/* ansi headers */
#include <ctype.h>
#include <errno.h>
#include <stdio.h>
/*#include <stdlib.h>*/
/*#include <string.h>*/

/* library headers */
#include <blkio.h>
#include <cbase.h>

/* local headers */
#include "basstr.h"
#include "rolodeck.h"
#include "rolodeck.i"

#ifndef EXIT_SUCCESS
#define EXIT_SUCCESS	(0)
#define EXIT_FAILURE	(1)
#endif

/* constants */
#define EXPFILE		("rolodeck.txt")	/* export file */
#define LMAXTRIES	(100)			/* maximum lock tries */
#define USAGE		("Usage: rolodeck")	/* usage message */
						/* rolodeck user requests */
#define RD_REQ_NEXT_CARD	('N')		/* next card */
#define RD_REQ_PREV_CARD	('P')		/* previous card */
#define RD_REQ_FIRST_CARD	('F')		/* first card*/
#define RD_REQ_LAST_CARD	('L')		/* last card */
#define RD_REQ_INS_CARD		('I')		/* insert card */
#define RD_REQ_DEL_CARD		('D')		/* delete card */
#define RD_REQ_SRCH_CARD	('S')		/* search for card */
#define RD_REQ_TOG_SORT		('T')		/* toggle sort field */
#define RD_REQ_CUR_CARD		('C')		/* current card */
#define RD_REQ_ALL_CARDS	('A')		/* all cards */
#define RD_REQ_IMPORT		('M')		/* import cards */
#define RD_REQ_EXPORT		('X')		/* export cards */
#define RD_REQ_HELP		('H')		/* help */
#define RD_REQ_QUIT		('Q')		/* quit */

/* function declarations */

int fmltolfm(char *t, const char *s, size_t n);
int lfmtofml(char *t, const char *s, size_t n);
int getcard(rolodeck_t *rdp);
int putcard(const rolodeck_t *rdp);
int putmenu(int sf);
int rdlock(cbase_t *cbp, int ltype);

/*man---------------------------------------------------------------------------
NAME
    rolodeck - card file

SYNOPSIS
     rolodeck

DESCRIPTION
     rolodeck is an example program for the cbase library.  In order
     to allow it to be compiled without requiring a specific screen
     management library, only a minimal user interface has been
     implemented.

NOTES
     Below are listed a few of the more important points to note when
     examining the rolodeck source code.

          o White space is significant in string data.  For
            instance, " data" != "data".  Leading and
            trailing white space is therefore usually
            removed before storing a string in a database.
            Also, embedded white space may be reduced to a
            single space.  The cvtss function included with
            cbase will perform these string operations.
          o Names are often input and displayed
            first-name-first.  For them to sort correctly in
            a database, however, they must be stored
            last-name-first.  The functions fmltolfm and
            lfmtofml are included with cbase to convert
            between these two formats.
          o bexit is used in place of exit to prevent loss
            of buffered data.

     The following notes concern locking.

          o Single-tasking applications can simply lock
            a cbase and leave it locked.
          o Locks are held for shortest time possible; a
            lock is never held during user input.
          o A write lock should not be used when only a read
            lock is required.
          o When a database file is unlocked, it may be
            modified by another process.  A record at a
            given file position may be deleted, and the
            empty slot possibly reused for a new record.
            Because of this, each time a file is locked,
            the current record must be located by performing
            a search on a unique key.
          o If locking multiple cbases, deadlock must be
            avoided (see The cbase Programmer's Guide).

------------------------------------------------------------------------------*/
int main(int argc, char *argv[])
{
	char		buf[256];		/* gp input buffer */
	cbase_t *	cbp	= NULL;		/* cbase pointer */
	int		found	= 0;		/* search flag */
	rolodeck_t	rd;			/* rolodeck record */
	int		rq	= 0;		/* user request */
	int		sf	= 0;		/* sort field */

	/* process command line options and arguments */
	if (argc != 1) {
		puts(USAGE);
		bexit(EXIT_FAILURE);
	}

	/* open rolodeck cbase */
	cbp = cbopen(ROLODECK, "r+", RDFLDC, rdfldv);
	if (cbp == NULL) {
		if (errno != ENOENT) {
			fprintf(stderr, "*** Error %d opening rolodeck.\n", errno);
			bexit(EXIT_FAILURE);
		}
		/* create rolodeck cbase */
		puts("Rolodeck does not exist.  Creating...");
		if (cbcreate(ROLODECK, sizeof(rolodeck_t), RDFLDC, rdfldv) == -1) {
			fprintf(stderr, "*** Error %d creating rolodeck.\n", errno);
			bexit(EXIT_FAILURE);
		}
		cbp = cbopen(ROLODECK, "r+", RDFLDC, rdfldv);
		if (cbp == NULL) {
			fprintf(stderr, "*** Error %d opening rolodeck.\n", errno);
			bexit(EXIT_FAILURE);
		}
	}
	if (cbrecsize(cbp) != sizeof(rolodeck_t)) {
		fprintf(stderr, "*** PANIC: incorrect record size.\n");
		bexit(EXIT_FAILURE);
	}

	puts("\n--------------------------------------------------");
	puts("|                    Rolodeck                    |");
	puts("--------------------------------------------------\n");

	/* set sort field */
	sf = RD_CONTACT;

	/* display menu */
	putmenu(sf);

	/* main loop */
	memset(&rd, 0, sizeof(rd));
	for (;;) {
		fputs("Enter selection:  ", stdout);
		fgets(buf, (int)sizeof(buf), stdin);
		cvtss(buf, buf, CVT_XSP | CVT_XCTL, sizeof(buf));
		rq = toupper(*buf);
		if (rq == RD_REQ_QUIT) {	/* quit rolodeck */
			break;
		}
		if (rq == NUL) {		/* default to next card */
			rq = RD_REQ_NEXT_CARD;
		}
		switch (rq) {
		case RD_REQ_NEXT_CARD:	/* next card */
			if (rdlock(cbp, CB_RDLCK) == -1) {
				fprintf(stderr, "*** Error %d read locking rolodeck.\n", errno);
				bexit(EXIT_FAILURE);
			}
			if (cbreccnt(cbp) == 0) {
				puts("The rolodeck is empty.\n");
				if (rdlock(cbp, CB_UNLCK) == -1) {
					fprintf(stderr, "*** Error %d unlocking rolodeck.\n", errno);
					bexit(EXIT_FAILURE);
				}
				continue;
			}
			/* use unique key field to set record cursor */
			found = cbkeysrch(cbp, RD_CONTACT, rd.rd_contact);
			if (found == -1) {
				fprintf(stderr, "*** Error %d searching for key.\n", errno);
				bexit(EXIT_FAILURE);
			}
			/* align cursor of sort key */
			if (cbkeyalign(cbp, sf) == -1) {
				fprintf(stderr, "*** Error %d aligning key.\n", errno);
				bexit(EXIT_FAILURE);
			}
			if (found == 1) {
				/* advance key (and rec) cursor 1 position */
				if (cbkeynext(cbp, sf) == -1) {
					fprintf(stderr, "*** Error %d finding next card.\n", errno);
					bexit(EXIT_FAILURE);
				}
			}
			if (cbrcursor(cbp) == NULL) {
				puts("End of deck.\n");
				if (rdlock(cbp, CB_UNLCK) == -1) {
					fprintf(stderr, "*** Error %d unlocking rolodeck.\n", errno);
					bexit(EXIT_FAILURE);
				}
				continue;
			}
			if (cbgetr(cbp, &rd) == -1) {
				fprintf(stderr, "*** Error %d reading card.\n", errno);
				bexit(EXIT_FAILURE);
			}
			if (rdlock(cbp, CB_UNLCK) == -1) {
				fprintf(stderr, "*** Error %d unlocking rolodeck.\n", errno);
				bexit(EXIT_FAILURE);
			}
			putcard(&rd);
			break;	/* case RD_REQ_NEXT_CARD: */
		case RD_REQ_PREV_CARD:	/* previous card */
			if (rdlock(cbp, CB_RDLCK) == -1) {
				fprintf(stderr, "*** Error %d read locking rolodeck.\n", errno);
				bexit(EXIT_FAILURE);
			}
			if (cbreccnt(cbp) == 0) {
				puts("The rolodeck is empty.\n");
				if (rdlock(cbp, CB_UNLCK) == -1) {
					fprintf(stderr, "*** Error %d unlocking rolodeck.\n", errno);
					bexit(EXIT_FAILURE);
				}
				continue;
			}
			/* use unique key field to set record cursor */
			found = cbkeysrch(cbp, RD_CONTACT, rd.rd_contact);
			if (found == -1) {
				fprintf(stderr, "*** Error %d searching for key.\n", errno);
				bexit(EXIT_FAILURE);
			}
			/* align cursor of sort key */
			if (cbkeyalign(cbp, sf) == -1) {
				fprintf(stderr, "*** Error %d aligning key.\n", errno);
				bexit(EXIT_FAILURE);
			}
			/* retreat key (and rec) cursor 1 position */
			if (cbkeyprev(cbp, sf) == -1) {
				fprintf(stderr, "*** Error %d finding previous card.\n", errno);
				bexit(EXIT_FAILURE);
			}
			if (cbrcursor(cbp) == NULL) {
				puts("Beginning of deck.\n");
				if (rdlock(cbp, CB_UNLCK) == -1) {
					fprintf(stderr, "*** Error %d unlocking rolodeck.\n", errno);
					bexit(EXIT_FAILURE);
				}
				continue;
			}
			if (cbgetr(cbp, &rd) == -1) {
				fprintf(stderr, "*** Error %d reading card.\n", errno);
				bexit(EXIT_FAILURE);
			}
			if (rdlock(cbp, CB_UNLCK) == -1) {
				fprintf(stderr, "*** Error %d unlocking rolodeck.\n", errno);
				bexit(EXIT_FAILURE);
			}
			putcard(&rd);
			break;	/* case RD_REQ_PREV_CARD: */
		case RD_REQ_FIRST_CARD:	/* first card */
			if (rdlock(cbp, CB_RDLCK) == -1) {
				fprintf(stderr, "*** Error %d read locking rolodeck.\n", errno);
				bexit(EXIT_FAILURE);
			}
			if (cbreccnt(cbp) == 0) {
				puts("The rolodeck is empty.\n");
				if(rdlock(cbp, CB_UNLCK) == -1) {
					fprintf(stderr, "*** Error %d unlocking rolodeck.\n", errno);
					bexit(EXIT_FAILURE);
				}
				continue;
			}
			if (cbkeyfirst(cbp, sf) == -1) {
				fprintf(stderr, "*** Error %d finding first card.\n", errno);
				bexit(EXIT_FAILURE);
			}
			if (cbgetr(cbp, &rd) == -1) {
				fprintf(stderr, "*** Error %d reading card.\n", errno);
				bexit(EXIT_FAILURE);
			}
			if (rdlock(cbp, CB_UNLCK) == -1) {
				fprintf(stderr, "*** Error %d unlocking rolodeck.\n", errno);
				bexit(EXIT_FAILURE);
			}
			putcard(&rd);
			break;	/* case RD_REQ_FIRST_CARD: */
		case RD_REQ_LAST_CARD:	/* last card */
			if (rdlock(cbp, CB_RDLCK) == -1) {
				fprintf(stderr, "*** Error %d read locking rolodeck.\n", errno);
				bexit(EXIT_FAILURE);
			}
			if (cbreccnt(cbp) == 0) {
				puts("The rolodeck is empty.\n");
				if (rdlock(cbp, CB_UNLCK) == -1) {
					fprintf(stderr, "*** Error %d unlocking rolodeck.\n", errno);
					bexit(EXIT_FAILURE);
				}
				continue;
			}
			if (cbkeylast(cbp, sf) == -1) {
				fprintf(stderr, "*** Error %d finding last card.\n", errno);
				bexit(EXIT_FAILURE);
			}
			if (cbgetr(cbp, &rd) == -1) {
				fprintf(stderr, "*** Error %d reading card.\n", errno);
				bexit(EXIT_FAILURE);
			}
			if (rdlock(cbp, CB_UNLCK) == -1) {
				fprintf(stderr, "*** Error %d unlocking rolodeck.\n", errno);
				bexit(EXIT_FAILURE);
			}
			putcard(&rd);
			break;	/* case RD_REQ_LAST_CARD: */
		case RD_REQ_INS_CARD:	/* insert new card */
			getcard(&rd);
			if (strlen(rd.rd_contact) == 0) {
				puts("Contact name cannot be blank.  Card not inserted.\n");
				memset(&rd, 0, sizeof(rd));
				continue;
			}
			if (rdlock(cbp, CB_WRLCK) == -1) {
				fprintf(stderr, "*** Error %d write locking rolodeck.\n", errno);
				bexit(EXIT_FAILURE);
			}
			if (cbinsert(cbp, &rd) == -1) {
				if (errno == CBEDUP) {
					printf("%s is already in the rolodeck.\n\n", rd.rd_contact);
					if (rdlock(cbp, CB_UNLCK) == -1) {
						fprintf(stderr, "*** Error %d unlocking rolodeck.\n", errno);
						bexit(EXIT_FAILURE);
					}
					continue;
				}
				fprintf(stderr, "*** Error %d inserting card.\n", errno);
				bexit(EXIT_FAILURE);
			}
			if (rdlock(cbp, CB_UNLCK) == -1) {
				fprintf(stderr, "*** Error %d unlocking rolodeck.\n", errno);
				bexit(EXIT_FAILURE);
			}
			putcard(&rd);
			break;	/* case RD_REQ_INS_CARD: */
		case RD_REQ_DEL_CARD:	/* delete current card */
			if (rdlock(cbp, CB_WRLCK) == -1) {
				fprintf(stderr, "*** Error %d write locking rolodeck.\n", errno);
				bexit(EXIT_FAILURE);
			}
			/* use unique key field to set record cursor */
			found = cbkeysrch(cbp, RD_CONTACT, rd.rd_contact);
			if (found == -1) {
				fprintf(stderr, "*** Error %d searching for key.\n", errno);
				bexit(EXIT_FAILURE);
			}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -