|
Newbie
Join Date: Jan 2007
Posts: 4
Rep Power: 0 
|
C code submission - simple database
Hi, im quite new to these forums, in fact this is my first post =]. For a while, i worked on a simple database program and finished it several months ago and am in the process of getting rid of some code on my machine including the program, but before i did that, i wanted to post this in the hope that it might be useful to someone else... it's features include creating files, command line processing with getopt_long from the standard GNU C library on Linux systems, and searching. I'll be on these forums from time to time, so if there are any suggestions for improvement of the code, please feel free to say so. Here it is:
/*
* A simple address book program to keep track
* of information for people you know, with user-defined
* functions for dealing with file formatting, and support
* for command-line parameters.
*/
#include <stdio.h>
#include <string.h>
#include <getopt.h>
#define TAB '\t'
#define MAX_BLOCK 20
#define MAXLINE 80
#define TRUE 1
#define FALSE 0
struct _PersonalInfo
{
char name[20];
char lastname[20];
char phone_number[20];
char workplace[30];
};
typedef struct _PersonalInfo PersonalInfo;
void get_block(char *line, char *cs, const char delimiter);
void print_record(PersonalInfo *pInfo);
void get_record(char *line, PersonalInfo *pInfo);
void app(PersonalInfo *pInfo, FILE *fp);
void fetch(char buffer[]);
int search(PersonalInfo *pInfo, char search_criteria[]);
void print_usage(const char *prog_name);
/*
* main driver program, with basic error checking for the
* command line parameters first, set file editing modes,
* and finally, if all went well enter a loop to fetch
* records from the file.
*/
int main(int argc, char *argv[])
{
FILE *fp;
PersonalInfo info, *pInfo = &info;
char buf[MAXLINE];
char *mode = "r";
int ret_val, srch = 0, found_records = 0;
char srch_term[MAX_BLOCK];
unsigned short int j = 0;
/*
* store program name for use by the
* print_usage() function and create arrays
* of short & long options for getopt_long.
*/
const char *program_name = argv[0];
const char *const shrt_optns = "ahs";
const struct option lng_optns[] = {
{"help", 0, NULL, 'h'},
{"append", 0, NULL, 'a'},
{"search", 0, NULL, 's'},
{NULL, 0, NULL, 0} /* required */
};
int next_option;
/*
* if insufficient command line options, print
* a message and exit with error code.
*/
if(argc < 2)
{
print_usage(program_name);
}
/* examine command line parameters */
do
{
next_option = getopt_long(argc, argv, shrt_optns, lng_optns, NULL);
switch(next_option)
{
case 'a':
mode = "a";
break;
case 'h':
print_usage(program_name);
break;
case 's':
srch = 1;
printf("Search For: ");
fetch(srch_term);
printf("\n");
break;
case '?':
exit(-1);
break;
case -1:
/* done with options */
break;
}
} while(next_option != -1);
/* open file */
if((fp = fopen(argv[optind], mode)) == NULL)
{
fprintf(stderr, "%s: Error: Cannot open file.\n", argv[0]);
exit(-1);
}
if(*mode == 'a')
app(pInfo, fp);
/* read in lines until EOF */
while(fgets(buf, 80, fp))
{
get_record(buf, pInfo);
if(srch == TRUE)
{
ret_val = search(pInfo, srch_term);
if(ret_val)
found_records++;
}
else
{
print_record(pInfo);
j++;
}
}
if(found_records == 0 && srch == TRUE)
fprintf(stderr, "Cannot find search criteria!\n");
else
printf("Success! %d record(s) returned.\n",
(srch == FALSE) ? j : found_records);
fclose(fp);
return 0;
}
/* get_str: Fetch one block of information separated by tabs */
void get_block(char *line, char *cs, const char delimiter)
{
char buf[MAX_BLOCK];
static int i = 0;
while(line[i] != '\0')
{
if(line[i] == delimiter)
{
i++;
break;
}
else if(line[i] == '\n')
{
i = 0;
break;
}
*cs++ = line[i++];
}
*cs = '\0';
}
/* print_record: Print each text segment out as a record on separate lines */
void print_record(PersonalInfo *pInfo)
{
static int j = 1;
printf("Record No.: %d\n", j++);
printf("Firstname: %s\n", pInfo->name);
printf("Lastname: %s\n", pInfo->lastname);
printf("Phone No.: %s\n", pInfo->phone_number);
printf("Workplace: %s\n\n", pInfo->workplace);
}
/* get_record: Set each text piece into structure counterparts */
void get_record(char *line, PersonalInfo *pInfo)
{
get_block(line, pInfo->name, TAB);
get_block(line, pInfo->lastname, TAB);
get_block(line, pInfo->phone_number, TAB);
get_block(line, pInfo->workplace, TAB);
}
/* fetch: Store input from user */
void fetch(char buffer[])
{
int c, i;
int max = MAX_BLOCK;
i = 0;
while((c = getchar()) != '\n')
{
if(i >= max)
break;
buffer[i++] = c;
}
buffer[i] = '\0';
}
/* append: Write new record to end of file */
void app(PersonalInfo *pInfo, FILE *fp)
{
char line[MAXLINE];
printf("Firstname: ");
fetch(pInfo->name);
printf("Lastname: ");
fetch(pInfo->lastname);
printf("Phone Number: ");
fetch(pInfo->phone_number);
printf("Work: ");
fetch(pInfo->workplace);
/* construct line from input */
strcpy(line, pInfo->name);
strcat(line, "\t");
strcat(line, pInfo->lastname);
strcat(line, "\t");
strcat(line, pInfo->phone_number);
strcat(line, "\t");
strcat(line, pInfo->workplace);
strcat(line, "\n\0");
/* write it to file */
fputs(line, fp);
}
int search(PersonalInfo *pInfo, char search_criteria[])
{
if(strcmp(pInfo->name, search_criteria) == 0)
{
print_record(pInfo);
return TRUE;
}
else if(strcmp(pInfo->lastname, search_criteria) == 0)
{
print_record(pInfo);
return TRUE;
}
else if(strcmp(pInfo->phone_number, search_criteria) == 0)
{
print_record(pInfo);
return TRUE;
}
else if(strcmp(pInfo->workplace, search_criteria) == 0)
{
print_record(pInfo);
return TRUE;
}
return 0;
}
void print_usage(const char *prog_name)
{
fprintf(stderr,
"Usage: %s [optional-flags] file_name\n"
"--help -h print this information\n"
"--append -a add records or create new file if not present\n"
"--search -s find records in specified file\n",
prog_name);
exit(-1);
}
|