Advertisement
Guest User

Untitled

a guest
Apr 19th, 2012
190
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 3.69 KB | None | 0 0
  1. #include<stdio.h>
  2. #include<assert.h>
  3. #include<stdlib.h>
  4. #include<errno.h>
  5. #include<string.h>
  6.  
  7. #define MAX_DATA 512
  8. #define MAX_ROWS 100
  9.  
  10. struct Address{
  11.     int id;
  12.     int set;
  13.     char name[MAX_DATA];
  14.     char email[MAX_DATA];
  15.  
  16. };
  17.  
  18. struct Database{
  19.     struct Address rows[MAX_ROWS];// struct within struct rows of Address.
  20. };
  21.  
  22. struct Connection{
  23. FILE *file;
  24. struct Database *db;
  25.  
  26. };
  27.  
  28. void die (const char *message){
  29.  
  30.  
  31. if(errno){
  32.  
  33. perror(message);
  34. }else{
  35. printf("ERROR:%s\n",message);
  36.  
  37. }
  38. exit(1);// Check this out!
  39.  
  40. }
  41.  
  42. void Address_print(struct Address *addr){
  43.  
  44. printf("%d %s %s\n",addr->id,addr->name,addr->email);
  45. }
  46.  
  47. void Database_load(struct Connection *conn){
  48. int rc=fread(conn->db,sizeof(struct Database),1,conn->file);// important line,fread is new!
  49.  
  50. if(rc!=1)die("Failed to load database");
  51. }
  52.  
  53. struct Connection* Database_open(const char *filename,char mode){// check if Connection* or Connection *Database
  54. struct Connection *conn=malloc(sizeof(struct Connection));
  55. if(!conn) die("Memory Error");
  56.  
  57.  
  58. conn->db=malloc(sizeof(struct Database));
  59. if(!conn->db) die("Memory Error");
  60.  
  61. if (mode=='c'){
  62. conn->file=fopen(filename,'w');
  63. }
  64. else{
  65. conn->file=fopen(filename,'r+');
  66. if(conn->file){
  67. Database_load(conn);
  68. }
  69. }
  70. if(!conn->file) die("Failed to open the file");
  71. return conn;
  72.  
  73. }
  74.  
  75. void Database_close(struct Connection *conn){
  76.  
  77. if(conn){
  78. if(conn->file)fclose(conn->file);
  79. if(conn->db) free(conn->db);
  80. free(conn);
  81. }
  82. }
  83. void Database_write(struct Connection *conn){
  84.  
  85. rewind(conn->file);//New- word:rewind???
  86. int rc=fwrite(conn->db,sizeof(struct Database),1,conn->file);
  87. if(rc!=1)die("Failed to write database.");
  88.  
  89. rc=fflush(conn->file);
  90. if(rc==-1)die("Cannot flush database!");
  91. }
  92.  
  93. void Database_create(struct Connection *conn){
  94. int i=0;
  95. for(i=0;i<MAX_ROWS;i++){
  96. //make a prototype to initialise it.
  97.  
  98. struct Address addr={.id=i,.set=0};
  99. //  then just assign it
  100. conn->db->rows[i]=addr;
  101. }
  102. }
  103.  
  104.  
  105. void Database_set(struct Connection *conn, int id,const char *name,const char *email){
  106.  
  107. struct Address *addr=&conn->db->rows[id];
  108. if(addr->set)die("Already set,delete it first");
  109. addr->set=1;
  110. // WARNING:bug, read the "How to Break It" and fix this!
  111. char *res= strncpy(addr->name,name,MAX_DATA);//new key!!
  112. //demonstrate the strncpy bug!
  113. if(!res) die("Name copy failed!");
  114. res=strncpy(addr->email,email,MAX_DATA);
  115. if(!res)die("Email copy failed");
  116. }
  117. void Database_get(struct Connection *conn, int id){
  118. struct Address *addr=&conn->db->rows[id];
  119.  
  120. if(addr->set){
  121. Address_print(addr);
  122. }else{
  123.  
  124. die("ID is not set");
  125. }
  126. }
  127.  
  128. void Database_delete(struct Connection *conn, int id){
  129. struct Address addr={.id=id,.set=0};
  130. conn->db->rows[id]=addr;
  131.  
  132. }
  133. void Database_list(struct Connection *conn){
  134. int i=0;
  135. struct Database *db=conn->db;
  136.  
  137. for (i=0;i<MAX_ROWS;i++){
  138. struct Address *cur=&db->rows[i];
  139. if(cur->set){
  140. Address_print(cur);
  141. }
  142. }
  143. }
  144.  
  145. int main(int argc,char *argv[]){
  146.  
  147. if (argc<3)die("USAGE ex 17<dbfile> <action >[action params]");
  148.  
  149. char *filename=argv[1];
  150. char action=argv[2][0];
  151. struct Connection *conn=Database_open(filename,action);
  152. int id=0;
  153.  
  154. if (argc>3)id=atoi(argv[3]);// Convert String to number.
  155. if(id>=MAX_ROWS)die("There aren't that many records!");
  156.  
  157. switch(action){
  158.  
  159.     case 'c':
  160.         Database_create(conn);
  161.         Database_write(conn);
  162.         break;
  163.     case 'g':
  164.         if(argc!=4)die("Need an id to get");
  165.         Database_get(conn,id);
  166.         break;
  167.     case 's':
  168.         if(argc!=6) die("Need id, name,email to set");
  169.        
  170.         Database_set(conn,id,argv[4],argv[5]);
  171.         Database_write(conn);
  172.         break;
  173.     case 'l':
  174.         Database_list(conn);
  175.         break;
  176.     default:
  177.         die("Invalid action,only:c=create,g=get,s=set,d=del,l=list");
  178.         }
  179. Database_close(conn);
  180.  
  181. return 0;
  182.  
  183.  
  184.  
  185.  
  186.  
  187.  
  188. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement