Set Data change the data stored the current location of the iterator.
The following program illustrates the use of a red-black tree and an iterator.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <dict.h>
void *xmalloc(size_t size);
char *xstrdup(const char *s);
int
main(void)
{
rb_tree *tree;
rb_itor *itor;
FILE *fp;
char *p;
char buf[512];
int rv;
if ((fp = fopen("data.txt", "r")) == NULL) {
fprintf(stderr, "can't open data.txt\n");
exit(EXIT_FAILURE);
}
/*
* Set the allocation function for the library. This may not be a good idea
* except in trivial programs like this one.
*/
dict_set_malloc(xmalloc);
tree = rb_tree_new((dict_cmp_func)strcmp, free, free);
/*
* We expect the text file to contain lines like "key=value".
*/
while ((fgets(buf, sizeof(buf), fp)) != NULL) {
p = strchr(buf, '=');
if (!p) {
fprintf(stderr, "bad file syntax\n");
exit(EXIT_FAILURE);
}
*p++ = '\0';
if (!*p) {
fprintf(stderr, "bad file syntax\n");
exit(EXIT_FAILURE);
}
if ((rv = rb_tree_insert(tree, xstrdup(buf), xstrdup(p), 0)) != 0) {
fprintf(stderr, "duplicate key in file: '%s'\n", buf);
exit(EXIT_FAILURE);
}
}
rewind(fp);
while ((fgets(buf, sizeof(buf), fp)) != NULL) {
strtok(buf, '=');
if ((p = rb_tree_search(tree, buf)) == NULL) {
fprintf(stderr, "key '%s' not found in tree!\n", buf);
exit(EXIT_FAILURE);
}
printf("%s = %s\n", buf, p);
}
printf("\n");
fclose(fp);
/* Print every key and data pair that is in the tree, in order. */
itor = rb_itor_new(tree);
for (; rb_itor_valid(itor); rb_itor_next(itor))
printf("%s = %s\n", rb_itor_key(itor), rb_itor_data(itor));
rb_itor_destroy(itor);
/* Destroy the tree and free all the data in it. */
rb_tree_destroy(tree, TRUE);
exit(EXIT_SUCCESS);
}
void *
xmalloc(size_t size)
{
void *p;
if ((p = malloc(size)) == NULL) {
fprintf(stderr, "out of memory\n");
exit(EXIT_FAILURE);
}
return p;
}
char *
xstrdup(const char *s)
{
unsigned len;
len = strlen(s) + 1;
return memcpy(xmalloc(len), s, len);
}
At the risk of being repetitive, here is the same program, but this time it
uses the generic interface. (Some parts of the first listing are omitted for
brevity).
int
main(void)
{
dict *dct;
dict_itor *itor;
FILE *fp;
char *p;
char buf[512];
int rv;
if ((fp = fopen("data.txt", "r")) == NULL) {
fprintf(stderr, "can't open data.txt\n");
exit(EXIT_FAILURE);
}
/*
* Set the allocation function for the library so we dont have to worry
* about it running out of memory. This may not be a good idea except in
* trivial programs like this one.
*/
dict_set_malloc(xmalloc);
dct = rb_dict_new((dict_cmp_func)strcmp, free, free);
/*
* We expect the text file to contain lines like "key=value".
*/
while ((fgets(buf, sizeof(buf), fp)) != NULL) {
strtok(buf, "\n");
p = strchr(buf, '=');
if (!p) {
fprintf(stderr, "bad file syntax\n");
exit(EXIT_FAILURE);
}
*p++ = '\0';
if (!*p) {
fprintf(stderr, "bad file syntax\n");
exit(EXIT_FAILURE);
}
if ((rv = dict_insert(dct, xstrdup(buf), xstrdup(p), 0)) != 0) {
fprintf(stderr, "duplicate key in file: '%s'\n", buf);
exit(EXIT_FAILURE);
}
}
rewind(fp);
while ((fgets(buf, sizeof(buf), fp)) != NULL) {
strtok(buf, "=");
if ((p = dict_search(dct, buf)) == NULL) {
fprintf(stderr, "key '%s' not found in dict!\n", buf);
exit(EXIT_FAILURE);
}
printf("%s = %s\n", buf, p);
}
printf("\n");
fclose(fp);
/* Print every key and data pair that is in the dict, in order. */
itor = dict_itor_new(dct);
for (; dict_itor_valid(itor); dict_itor_next(itor))
printf("%s = %s\n", dict_itor_key(itor), dict_itor_data(itor));
dict_itor_destroy(itor);
/* Destroy the dict and free all the data in it. */
dict_destroy(dct, TRUE);
exit(EXIT_SUCCESS);
}
Now, if we wanted to use some other data structure than a red-black tree, such
as a splay tree, we could just change the line
dct = rb_dict_new(...)
to
dct = sp_dict_new(...)
'.
Copyright (C) 2001 Farooq Mela.
Comments, suggestions, bug fixes, etc, are
welcome.