Dictionary(内存操作,struc使用)

Posted on 2007-11-17 04:29  QT_pixy  阅读(688)  评论(0)    收藏  举报
关于字典的程序,可以在字典中增加单词,每个单词可以有最多10个翻译,可以从字典中删除单词。这个程序的特点就是使用malloc操作内存。大家知道C语言中操作内存是很高效但很危险的,很容易出现内存泄露(memory leak).这个程序需要用struc来在内存中建立结构。如果要练习对内存进行操作和struc的使用,这个程序是非常好的练习题目。最后,我使用unix下的内存检测工具来检查是否存在错误的内存操作。好的程序是能够合理的尽量节约的使用内存,所以这个程序限制了内存的最大使用量。
这个程序我认为我写的不错,有参考价值。
如需要此程序的原说明文档和test case以及内存检测工具的使用方法,请与我联系。
Write an ANSI-C dictionary that allows other services to access a database of words and their translations as well as allows for additions and deletions to the dictionary. As between most languages, each word can have multiple translations.

#include <stdio.h>
#include 
<stdlib.h>
#include 
<string.h>
#include 
"a2.h"

#define LOOP 1    /* continue the loop */

void free_wordlist(wordlist *head);   /* function declaration, free all allocated memory. Not include buffer */

int main(void)
{
    
int begin = 1;       /* at the beginning of the wordlist (no word in the list) */
    wordlist 
*head, *prev;   /* beginning of the wordlist and the previous word */
    prev 
= head = NULL;

    
char com1[] = "add";        /* command "add" */
    
char com2[] = "delete";       /* command "delete" */
    
char com3[] = "find";        /* command "find" */
    
char com4[] = "reverse";     /* command "reverse" */

    
char *buff;        /* buffer used for reading words */
 
    buff 
= (char *)malloc(2001);   /* allocate memory */
    
if(buff == NULL)     /* check if the program runs out of memory */
    
{
        printf(
"out of memory\n");
        exit(
1);
    }


    
while(LOOP)
    
{
        
char *str;       /* a string used for saving command word */

        scanf(
"%s", buff);     /* read string into buffer */

        str 
= (char *)malloc(strlen(buff) + 1);  /* allocate memory */
        
if(str == NULL)   /* chech if the program runs out of memory */
        
{
            printf(
"out of memory\n");
            free_wordlist(head);    
/* free all allocated memory, not include buffer */ 
            free(buff);     
/* free allocated memory of buffer */
            exit(
1);     /* exit the program */
        }

        strcpy(str, buff);   
/* copy the word from buffer */

        
if(!strcmp(str, com1))    /* command "add" */
        
{   
            
char *w, *t;     /* two strings used for saving words */

            scanf(
"%s", buff);   /* read word into buffer */
            w 
= (char *)malloc(strlen(buff) + 1);  /* allocate memory */
            
if(w == NULL)    /* check if the program runs out of memory */
            
{
                printf(
"out of memory\n");
                free_wordlist(head);   
/* free all allocated memory, not include buffer */
                free(str);        
/* free allocated memory of str */ 
                free(buff);
                exit(
1);
            }

            strcpy(w, buff);     
/* copy word from buffer */

            scanf(
"%s", buff);     /* read the translation of the word */
            t 
= (char *)malloc(strlen(buff) + 1);
            
if(t == NULL)
            
{
                printf(
"out of memory\n");
                free_wordlist(head);
                free(w);
                free(str);
                free(buff);
                exit(
1);
            }

            strcpy(t, buff);  
/* copy from buffer */

            
if (begin)   /* empty word list */
            
{
                head 
= (wordlist *)malloc(sizeof(wordlist)); /* allocate memory for a word */
                
if(head == NULL)  /* check if the program runs out of memory */
                
{
                    printf(
"out of memory\n");
                    free_wordlist(head);   
/* free the word list */
                    free(t);
                    free(w);
                    free(str);
                    free(buff);
                    exit(
1);
                }

                head
->word = (char *)malloc(strlen(w) + 1); /* allocate memory for the name of word */
                
if(head->word == NULL)
                
{
                    printf(
"out of memory\n");
                    free_wordlist(head);
                    free(t);
                    free(w);
                    free(str);
                    free(buff);
                    exit(
1);
                }

                strcpy(head
->word, w);

                head
->num_translations = 0;  /* initialize the number of translations */

                
/* allocate memory for the translation of the word */
                head
->translation[head->num_translations] = (char *)malloc(strlen(t) + 1);
                
if(head->translation[head->num_translations] == NULL)
                
{
                    printf(
"out of memory\n");
                    free_wordlist(head);
                    free(t);
                    free(w);
                    free(str);
                    free(buff);
                    exit(
1);
                }

                strcpy(head
->translation[head->num_translations], t);

                head
->num_translations++;  /* the number of translations increase */

                head
->next = NULL;   /* set the next word NULL */
                prev 
= head;        /* set the previous word to head */ 

                begin 
= 0;   /* the word list is not empty */
            }

            
else   /* not empty word list */
            
{
                
int new = 1;  /* new word */
                wordlist 
*current;
                wordlist 
*l;

                
for(l = head; l != NULL; l = l->next)  /* check if it is new word */
                
{
                    
if (strcmp(l->word, w) == 0)
                    
{
                        current 
= l;
                        
new = 0;    /* is not new word */
                        
break;
                    }

                }


                
if(new == 1)   /* it is new word */
                
{
                    
/* allocate memory for new word */
                    current 
= (wordlist *)malloc(sizeof(wordlist));
                    
if(current == NULL) /* program runs out of memory */
                    
{
                        printf(
"out of memory\n");
                        free_wordlist(head);  
/* free the word list */
                        free(t);
                        free(w);
                        free(str);
                        free(buff);
                        exit(
1);
                    }


                    current
->num_translations = 0;  /* initialize the number of translations */
                

                    current
->word = (char *)malloc(strlen(w) + 1); /* allocate memory for the name of word */ 
                    
if(current->word == NULL)
                    
{
                        printf(
"out of memory\n");
                        free_wordlist(head);
                        free(t);
                        free(w);
                        free(str);
                        free(buff);
                        exit(
1);
                    }

                    strcpy(current
->word, w);  /* copy word from w */
                }

                
                
if(current->num_translations < 10/* 10 translations at most */
                
{

                    
int i, same;
                    same 
= 0;  /* initialize to not exits */
                    
/* check if the translation exits */
                    
for(i = 0; i < current->num_translations; i++)
                    
{
                        
if(!strcmp(current->translation[i], t))
                            same 
= 1;
                    }

                    
/* not exits */
                    
if(!same)
                    
{
                        
/* allocate memory for the translation of word */
                        current
->translation[current->num_translations] = (char *)malloc(strlen(t) + 1);
                        
if(current->translation[current->num_translations] == NULL)
                        
{
                            printf(
"out of memory\n");
                            free_wordlist(head);
                            free(t);
                            free(w);
                            free(str);
                            free(buff);
                            exit(
1);
                        }

                        strcpy(current
->translation[current->num_translations], t);
                        current
->num_translations++;
                    }

                }


                
if(new == 1/* if the word is new */
                
{
                    current
->next = NULL;
                    prev
->next = current;  /* connect this word to the previous word */
                    prev 
= current;
                }


                begin 
= 0;  /* word list is not empty */
            }
 
            free(w);  
/* free allocated memory of "w" */
            free(t);  
/* free allocated memory of "t" */
        }

        
else if(!strcmp(str, com2))  /* command delete */
        
{
            
char *w;      /* string used for saving word */
            wordlist 
*l, *p;

            scanf(
"%s", buff);    /* read word into buffer */
            w 
= (char *)malloc(strlen(buff) + 1);  /* allocate memory for "w" */
            
if(w == NULL)  /* check if the program runs out of memory */
            
{
                printf(
"out of memory\n");
                free_wordlist(head);
                free(str);
                free(buff);
                exit(
1);
            }


            strcpy(w, buff);   
/* copy word from buffer */

            
/* find word. p is the previous word */
            p 
= l;
            
int i;
            
for(i = 0, l = head; l != NULL; l = l->next, i++)
            
{
                
if (strcmp(l->word, w) == 0)
                    
break;
                p 
= l;
            }


            
if(l == NULL)  /* nothing can be deleted */
                ;
            
else if(i == 0/* deleting the first element */
            
{
                
/* free translations */
                
int x;
                
for(x = 0; x < head->num_translations; x++)
                    free(head
->translation[x]);
                        
                
if(head->next == NULL)  /* deleting the first element, which is also the last */
                
{
                    begin 
= 1;
                    
                    free(head
->word);
                    free(head);
                    head 
= NULL;
                }

                
else    /* deleting the first element, it is not the last */
                
{
                    wordlist 
*tmp = head->next;
                    
                    free(head
->word);
                    free(head);
                    head 
= tmp;
                }

            }

            
else  /* the other words */
            
{
                
/* free translations */                
                
int x;
                
for(x = 0; x < l->num_translations; x++)
                    free(l
->translation[x]);
    
                
if(l->next == NULL)  /* deleting the last word */
                    prev 
= p;

                p
->next = l->next;
                free(l
->word);
                free(l);

            }


            free(w);   
/* free memory */
        }

        
else if(!strcmp(str, com3)) /* command "find" */
        
{
            
char *w;
            wordlist 
*l;

            scanf(
"%s", buff);  /* read word into buffer */
            w 
= (char *)malloc(strlen(buff) + 1);
            
if(w == NULL)
            
{
                printf(
"out of memory\n");
                free_wordlist(head);
                free(str);
                free(buff);
                exit(
1);
            }


            strcpy(w, buff);   
/* copy word from buffer */

            
for(l = head; l != NULL; l = l->next)  /* find word */
            
{
                
if (strcmp(l->word, w) == 0)
                    
break;
            }


            
if(l == NULL)  /* can not find word */
                printf(
"cannot find word\n");
            
else
            
{
                
int i;
                
/* print all the translations of the word */
                
for(i = 0; i < l->num_translations; i++)
                
{
                    printf(
"%s\n", l->translation[i]);
                }

            }


            free(w);   
/* free allocated memory */
        }

        
else if(!strcmp(str, com4))  /* command "reverse" */
        
{
            
char *t;
            wordlist 
*l;

            scanf(
"%s", buff);   /* read word into buffer */
            t 
= (char *)malloc(strlen(buff) + 1);
            
if(t == NULL)
            
{
                printf(
"out of memory\n");
                free_wordlist(head);
                free(str);
                free(buff);
                exit(
1);
            }

            strcpy(t, buff);  
/* copy word from buffer */

            
int found;  /* find the word */
            found 
= 0/* initialize to not find */

            
for(l = head; l != NULL; l = l->next)
            
{
                
int i;
                
for(i = 0; i < l->num_translations; i++)
                
{
                    
if (strcmp(l->translation[i], t) == 0)
                    
{
                        printf(
"%s\n", l->word);  /* print the word */
                        found 
= 1;  /* find the word */
                    }

                }

            }


            
if(found == 0)  /* can not find the word */
                printf(
"cannot find word\n");

            free(t);  
/* free allocated memory */
        }

        
else  /* EOF or other command */
        
{
            free_wordlist(head);  
/* free alloacated memory of the word list */
            free(str);     
/* free allocated memory of "str", which is used for saving command name */
            free(buff);    
/* free allocated memory of buffer */

            
return 0;
        }


        buff[
0= '\0';   /* initialize buffer */
        free(str);   
/* free allocated memory of "str", which is used for saving command name */
    }


    
return 0;
}


/* free allocated memory of the word list function */
void free_wordlist(wordlist *head)
{
    wordlist 
*l, *tmp;

    
for(l = head; l != NULL; l = tmp)
    
{
        
int i;
        
for(i = 0; i < l->num_translations; i++)
            free(l
->translation[i]);   /* free allocated memory of the translations of the words */

        free(l
->word);  /* free allocated memory of the word name */
        tmp 
= l->next;
        free(l);
        
/* free allocated memory of the word */
    }

}

博客园  ©  2004-2025
浙公网安备 33010602011771号 浙ICP备2021040463号-3