C/Structure/Structure Serialization

Материал из C\C++ эксперт
Перейти к: навигация, поиск

scan a file and print out a list of words in ASCII order

/*
Practical C Programming, Third Edition
By Steve Oualline
Third Edition August 1997 
ISBN: 1-56592-306-5
Publisher: O"Reilly
*/
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include <stdlib.h>    
struct node {
    struct node    *left;       /* tree to the left */
    struct node    *right;      /* tree to the right */
    char           *word;       /* word for this tree */
};
/* the top of the tree */
static struct node *root = NULL;
/*
 * memory_error -- write error and die                  *
 */
void memory_error(void)
{
    fprintf(stderr, "Error:Out of memory\n");
    exit(8);
}
/*
 * save_string -- save a string on the heap             *
 *                                                      *
 * Parameters                                           *
 *      string -- string to save                        *
 *                                                      *
 * Returns                                              *
 *      pointer to malloc-ed section of memory with     *
 *      the string copied into it.                      *
 */
char *save_string(char *string)
{
    char *new_string;   /* where we are going to put string */
    new_string = malloc((unsigned) (strlen(string) + 1));
    if (new_string == NULL)
        memory_error();
    strcpy(new_string, string);
    return (new_string);
}
/*
 * enter -- enter a word into the tree                  *
 *                                                      *
 * Parameters                                           *
 *      node -- current node we are looking at          *
 *      word -- word to enter                           *
 */
void enter(struct node **node, char *word)
{
    int  result;        /* result of strcmp */
    char *save_string(char *);  /* save a string on the heap */
    /* 
     * If the current node is null, we have reached the bottom
     * of the tree and must create a new node.
     */
    if ((*node) == NULL) {
  /* Allocate memory for a new node */
        (*node) = malloc(sizeof(struct node));
        if ((*node) == NULL)
            memory_error();
  /* Initialize the new node */
        (*node)->left = NULL;
        (*node)->right = NULL;
        (*node)->word = save_string(word);
  return;
    }
    /* Check to see where the word goes */
    result = strcmp((*node)->word, word);
    /* The current node already contains the word, no entry necessary */
    if (result == 0)
        return;
    /* The word must be entered in the left or right sub-tree */
    if (result < 0)
        enter(&(*node)->right, word);
    else
        enter(&(*node)->left, word);
}
/*
 * scan -- scan the file for words                      *
 *                                                      *
 * Parameters                                           *
 *      name -- name of the file to scan                *
 */
void scan(char *name)
{
    char word[100];     /* word we are working on */
    int  index;         /* index into the word */
    int  ch;            /* current character */
    FILE *in_file;      /* input file */
    in_file = fopen(name, "r");
    if (in_file == NULL) {
        fprintf(stderr, "Error:Unable to open %s\n", name);
        exit(8);
    }
    while (1) {
        /* scan past the whitespace */
        while (1) {
            ch = fgetc(in_file);
            if (isalpha(ch) || (ch == EOF))
                break;
        }
        if (ch == EOF)
            break;
        word[0] = ch;
        for (index = 1; index < sizeof(word); ++index) {
            ch = fgetc(in_file);
            if (!isalpha(ch))
                break;
            word[index] = ch;
        }
        /* put a null on the end */
        word[index] = "\0";
        enter(&root, word);
    }
    fclose(in_file);
}
/*
 * print_tree -- print out the words in a tree          *
 *                                                      *
 * Parameters                                           *
 *      top -- the root of the tree to print            *
 */
void print_tree(struct node *top)
{
    if (top == NULL)
        return;                 /* short tree */
    print_tree(top->left);
    printf("%s\n", top->word);
    print_tree(top->right);
}
int main(int argc, char *argv[])
{
    if (argc != 2) {
        fprintf(stderr, "Error:Wrong number of parameters\n");
        fprintf(stderr, "      on the command line\n");
        fprintf(stderr, "Usage is:\n");
        fprintf(stderr, "    words "file"\n");
        exit(8);
    }
    scan(argv[1]);
    print_tree(root);
    return (0);
}


Write structure into file

/*
C & Data Structures
Published in Feb 2004 by CHARLES RIVER MEDIA
Author: P. S. Deshpande, O. G. Kakde
SKU: 1584503386
ISBN: 1584503386
*/ 
  
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define MAX 50

typedef struct {
    char  name[10];
    int key;
} file_record;
/* this function adds the relatiuve addres to the index for a key */
void create_index(long index[], int key, long rel_add ) {
    index[key] = rel_add;
}
/* this function writes a record to the file */
void write_rec(FILE *fp, file_record rec) {
   fwrite(&rec,sizeof(rec),1,fp);
}
void main() {
    long rel_add;
    int key;
    file_record frec;
    long index[MAX];/* an index list*/
    int n,i;
    FILE *recfile=NULL,*ifile=NULL;
    /* this initializes the index list to all ? */
    for(i=0; i< MAX; i++)
        index[i]= (-1);
    recfile=fopen("mfile","w");
    if(recfile == NULL) {
        printf("Error in openeing file mfile\n");
        exit(0);
    }
    rel_add = 0 ;
    do {
        printf(" Enter the data vlue and the key of the record to be added to file mfile\n");
        scanf("%s %d",frec.name,&frec.key);
        while(index[frec.key] != (-1)) {
            printf(" A record with this key value already exist in a file enter record key value\n");
            scanf("%s %d",frec.name,&frec.key);
        }
        create_index(index,frec.key,rel_add);
         write_rec(recfile,frec);
        rel_add =  ftell(recfile); 
        /* this sets the relative address for the next record to be 
      the value of current file position pointer in bytes from 
      the beginning of the file */
         printf("Enter 1 to continue adding records to the file\n");
         scanf("%d",&n);
    }while(n == 1);
   
    ifile=fopen("index_file","w");
         
    if(ifile == NULL) {
       printf("Error in openeing file index_file\n");
         exit(0);
    }
    
    fwrite(index,sizeof(index),1,ifile);/*writes the complete index into the index_file */
    fclose(recfile);
    fclose(ifile);
    printf("Enter 1 if you want to retrieve a record\n");
    scanf("%d",&n);
    
    if( n == 1) {
       ifile=fopen("index_file","r");
       if(ifile == NULL) {
           printf("Error in openeing file index_file\n");
           exit(0);
       }
       fread(index,sizeof(index),1,ifile);
       
       /* reads the complete index into the index list from the index_file*/
       fclose(ifile);
       recfile=fopen("mfile","r");
       
       if(recfile == NULL) {
           printf("Error in openeing file mfile\n");
           exit(0);
       }
    }
    printf("THE CONTENTS OF FILE IS \n");
    
    while( (fread(&frec,sizeof(frec),1,recfile)) != 0)
         printf("%s %d\n",frec.name,frec.key);
    
    do {
        printf("Enter the key of the record to be retrieved\n");
        scanf("%d",&key);
        rel_add = index[key]; /*gets the relative address of the record from index list */
        if( (fseek(recfile,rel_add,SEEK_SET))!= 0) {
             printf("Error\n");
             exit(0);
        }
        fread(&frec,sizeof(frec),1,recfile);
        printf("The data value of the retrieved record is %s\n",frec.name);
        printf("Enter 1 if you want to retrieve a record\n");
        scanf("%d",&n);
    } while(n == 1);
    
    fclose(recfile);
}