fork(1) download
  1. #include <cstdio>
  2. #include <cstdlib>
  3. #include <string>
  4. #include <iostream>
  5. using namespace std;
  6.  
  7. // Function Headers
  8. void Create();
  9. void Dump();
  10. void Insert();
  11. void Delete();
  12. void Print();
  13. int AddDigits(char * psSSN);
  14. FILE * Find(char * key);
  15. void Retrieve();
  16.  
  17. // Global Variables
  18. int mnRecordLength = 46; // Length of each record 3(Delete Flag) + 10(SSN) + 21(Name) + 10(Salary) + 2(CRLF)
  19. int mnHeaderSize = 6; // The size of our header record holding number of records in overflow
  20. FILE *mioHashFile; // Internal file pointer for our IO commands
  21. int mnOverlowRecords; // number of records in overflow
  22.  
  23. // Main program that presents a menu of options to the user and calls the various functions
  24. int main()
  25. {
  26. char sOption;
  27. cout << "Enter a Menu Selection - (C)reate, (I)nsert, (R)etrieve, X=Delete, (P)rint, (D)ump, (Q)uit" << endl;
  28. cin >> sOption;
  29. while (sOption != 'Q')
  30. {
  31. switch ( sOption )
  32. {
  33. case 'C':
  34. Create();
  35. break;
  36. case 'I':
  37. Insert();
  38. break;
  39. case 'D':
  40. Dump();
  41. break;
  42. case 'X':
  43. Delete();
  44. break;
  45. case 'P':
  46. Print();
  47. break;
  48. case 'R':
  49. Retrieve();
  50. break;
  51. default:
  52. cout << "Invalid Menu Option Entered \n";
  53. }
  54.  
  55. cout << "Enter a Menu Selection - (C)reate, (I)nsert, (R)etrieve, X=Delete, (P)rint, (D)ump, (Q)uit" << endl;
  56. cin >> sOption;
  57.  
  58. }
  59. return 0;
  60. }
  61. // This function opens the emp file for output which will remove all records already out there
  62. // It then writes a header record that contains the overflow record number (0)
  63. // and then writes 10 empty records into the file
  64. void Create()
  65. {
  66. mioHashFile = fopen ("emp", "w");
  67.  
  68. //Write a Header Record that contains the number of the overflow records written (0)
  69. fprintf (mioHashFile, "%4d\n", 0);
  70. // Initialize emp file with fixed length dummy records.
  71. // Assume there are 10 records in the file.
  72. for (int nRecords = 0; nRecords < 10; nRecords++)
  73. {
  74. fprintf (mioHashFile, "%3d%10s%21s%10.2f\n", -1, "x", "x", 0.0);
  75. }
  76. fclose(mioHashFile);
  77. cout << "create complete\n";
  78. return;
  79. }
  80. // This function is used to insert a new record into out employee file.
  81. // It first calculates the hash for the record and reads that record to determine
  82. // if it has been used before. If it has not, it writes the new record and returns.
  83. // If the primary data record has been used, it then checks to see if either the
  84. // primary record or some record is overflow matches the key to the new record, and
  85. // if a match is found, it reports this and returns.
  86. // While searching for a match, the program records the first deleted record so that it
  87. // might be used again.
  88. // If no match is found, and a deleted record was found, the new record is written over
  89. // the deleted record and the function returns. If no deleted record was found
  90. // the overflow pointer is accessed, the new record written to overflow, and the overflow
  91. // pointer incremented.
  92. void Insert()
  93. {
  94. int ioDeleteRecordPointer = 0; // Pointer to the address of the first deleted record
  95. // Data accepted from CIN
  96. char sInSSN[10], sInName[21];
  97. float nInSalary;
  98. int nDeleteSwitch;
  99.  
  100. // Data from the record being examined
  101. char sSSN[10], sName[21]; /* emp record read from file */
  102. float nSalary;
  103.  
  104. int nSSN; /* integer value of primary key string sInSSN */
  105. int nHashKey; /* hash value = (key % 10) */
  106. long nFileOffset; /* offset */
  107.  
  108.  
  109. mioHashFile = fopen ("emp", "r+");
  110. //Get the overflow header from the file
  111. fscanf (mioHashFile,"%d",&mnOverlowRecords);
  112.  
  113. cout << "Please enter SSN, name and salary separated by blanks\n";
  114. cin >> sInSSN >> sInName >> nInSalary;
  115.  
  116.  
  117. // convert primary key string to integer by folding and then division
  118. nSSN = AddDigits(sInSSN);
  119. nHashKey = nSSN % 10;
  120.  
  121. // calculate the address in the file for the primary record, set the file pointer
  122. // there and read the record
  123. nFileOffset = (nHashKey *mnRecordLength) + mnHeaderSize;
  124. fseek (mioHashFile, nFileOffset, 0);
  125. fscanf (mioHashFile, "%d%s%s%f", &nDeleteSwitch, sSSN, sName, &nSalary);
  126.  
  127. if (nDeleteSwitch == -1) // virgin record, insert immediately
  128. {
  129. fseek (mioHashFile, nFileOffset, 0);
  130. fprintf(mioHashFile,"%3d%10s%21s%10.2f\n", 0, sInSSN, sInName, nInSalary);
  131. fclose (mioHashFile);
  132. printf ("insert complete\n");
  133. return;
  134. }
  135.  
  136. // A live record with the same SSN - Report it and get out
  137. if (nDeleteSwitch == 0 && strcmp(sInSSN,sSSN)==0)
  138. {
  139. printf ("SSN already in file, insert terminated\n");
  140. fclose (mioHashFile);
  141. return;
  142. }
  143.  
  144. // Found deleted record. Use ioDeleteRecordPointer to remember it.
  145. if (nDeleteSwitch == 1)
  146. {
  147. ioDeleteRecordPointer = nFileOffset;
  148. }
  149.  
  150. // Search through overflow to see if the record exists there
  151. for (int nRecords = 0; nRecords < mnOverlowRecords; nRecords++)
  152. {
  153. nFileOffset = ((nRecords + 10) * mnRecordLength) + mnHeaderSize;
  154. fseek (mioHashFile, nFileOffset, 0);
  155. fscanf (mioHashFile, "%d%s%s%f", &nDeleteSwitch, sSSN, sName, &nSalary);
  156.  
  157. // Duplicate primary key in overflow area. Abort insert.
  158. if (nDeleteSwitch == 0 && strcmp(sInSSN,sSSN)==0)
  159. {
  160. printf("SSN already in file, insert terminated\n");
  161. fclose (mioHashFile);
  162. return;
  163. }
  164. // Found a deleted record. If we don't already have one, set the deleted record pointer
  165. if ( ioDeleteRecordPointer == 0 && nDeleteSwitch == 1)
  166. {
  167. ioDeleteRecordPointer =nFileOffset;
  168. }
  169. } //next nRecords
  170.  
  171. // We are now here, so we have searched through primary and overflow and
  172. // did not find a duplicate SSN
  173. // See if we found a deleted record we can reuse
  174. if (ioDeleteRecordPointer != 0 )
  175. {
  176. fseek (mioHashFile, ioDeleteRecordPointer, 0);
  177. fprintf(mioHashFile,"%3d%10s%21s%10.2f\n", 0, sInSSN, sInName, nInSalary);
  178.  
  179. }
  180. // No deleted record. Get the next overflow record, create it and update the Overlow HEader
  181. else
  182. {
  183. fseek (mioHashFile, (mnOverlowRecords + 10) * mnRecordLength + mnHeaderSize, 0);
  184. fprintf(mioHashFile,"%3d%10s%21s%10.2f\n", 0, sInSSN, sInName, nInSalary);
  185. rewind (mioHashFile); /* go back and update header in overflow */
  186. fprintf(mioHashFile, "%4d\n", ++mnOverlowRecords); /* update overflow file size */
  187. }
  188. // All done - Say Goodbye!!
  189. fclose(mioHashFile);
  190. printf("insert complete \n");
  191. return;
  192.  
  193. }
  194. // This function simply uses the DOS Type command to dump the contents of the file
  195. void Dump()
  196. {
  197. printf("emp\n");
  198. system("type emp");
  199. return;
  200. }
  201.  
  202. // The Find Function is passed a social security number key
  203. // It will look through the primary and overflow records for a
  204. // the same key and if found pass back a file pointer to the beginning
  205. // of that record. If nothing is found, a zero is passed back.
  206. FILE * find(char * psSSN) /* key is pointer to SSN */
  207. {
  208. int nSSN, nHashKey;
  209. long nFileOffset;
  210. int nDeleteSwitch;
  211. char sSSN[10], sName[21];
  212. float nSalary;
  213.  
  214. nSSN = AddDigits(psSSN);
  215. nHashKey = nSSN % 10; /* calculate hash value */
  216. nFileOffset = nHashKey * (mnRecordLength) + mnHeaderSize; /* convert slot number to offset */
  217.  
  218. mioHashFile = fopen("emp", "r+");
  219. // Read in the current overflow counter
  220. fscanf (mioHashFile,"%d",&mnOverlowRecords);
  221.  
  222. //Go to the hashed data record
  223. fseek (mioHashFile, nFileOffset, 0);
  224. fscanf (mioHashFile, "%d", &nDeleteSwitch); /* read delete flag */
  225.  
  226. // If we hashed to a virgin record, then key not in table - Return 0
  227. if (nDeleteSwitch == -1)
  228. {
  229. fclose (mioHashFile);
  230. return 0;
  231. }
  232.  
  233. fscanf(mioHashFile, "%s", sSSN); /* read ssn */
  234. // If this is a live record and the keys match, set file pointer back to the beginning and pass it back
  235. if (nDeleteSwitch == 0 && (strcmp(psSSN,sSSN) == 0))
  236. {
  237. fseek (mioHashFile, nFileOffset, 0);
  238. return mioHashFile;
  239. }
  240.  
  241. // Not found in primary. Switch to overflow going through it sequentially
  242. fseek (mioHashFile, 10*mnRecordLength + mnHeaderSize, 0);
  243. for (int nRecords = 0; nRecords < mnOverlowRecords; nRecords++)
  244. {
  245. nFileOffset = ftell (mioHashFile); /* remember the position of next record */
  246. fscanf (mioHashFile, "%d%s%s%f", &nDeleteSwitch, sSSN, sName, &nSalary); /* read entire
  247. record to get past it for next iteration */
  248.  
  249. if (nDeleteSwitch == 0 && (strcmp (psSSN,sSSN) == 0)) /* record found, return
  250. open file pointer */
  251. {
  252. fseek (mioHashFile, nFileOffset, 0);
  253. return mioHashFile;
  254. }
  255. }
  256. // Record not found. Close file and return 0
  257. fclose (mioHashFile);
  258. return 0;
  259. }
  260.  
  261. // The Retreive Function uses the Find Command to set the file pointer
  262. // at the appropriate record. It then reads the record and prints out
  263. // the data in the record.
  264. void Retrieve()
  265. {
  266. char sInSSN[10];
  267. int nDeleteSwitch;
  268. char sSSN[10], sName[21];
  269. float nSalary;
  270.  
  271. printf("Please enter SSN\n");
  272. scanf ("%s", sInSSN);
  273.  
  274. mioHashFile = find(sInSSN);
  275. if (mioHashFile == 0)
  276. {
  277. printf("SSN not found\n");
  278. return;
  279. }
  280.  
  281. fscanf (mioHashFile, "%d%s%s%f", &nDeleteSwitch, sSSN, sName, &nSalary);
  282. printf ("ssn = %s name = %s salary = %10.2f\n", sSSN, sName, nSalary);
  283. fclose(mioHashFile);
  284. printf ("retrieve complete\n");
  285. return;
  286. }
  287.  
  288. // The Delete function calls the Find Function. If Find returns
  289. // an active file pointer, then the routine updates the
  290. // the delete flag for location returned.
  291. void Delete()
  292. {
  293. char sSSN[10];
  294.  
  295. printf("Please enter the SSN of the employee to be fired.\n");
  296. scanf ("%s", sSSN);
  297. //find returns 0 or open file pointer positioned to beginning of found employee record
  298. mioHashFile = find (sSSN);
  299.  
  300. // employee not found
  301. if (mioHashFile == 0)
  302. {
  303. printf("Employee does not exist.\n");
  304. return;
  305. }
  306. // employee found, set delete flag for employee
  307. fprintf (mioHashFile, "%3d", 1);
  308.  
  309. fclose(mioHashFile);
  310. printf("Firing complete.\n");
  311. return;
  312. }
  313.  
  314. //This function prints out all the records in the employee file including
  315. //primary and overflow records.
  316. void Print()
  317. {
  318. int nDeleteSwitch;
  319. char sSSN[10], sName[21];
  320. float nSalary;
  321.  
  322. printf("SSN NAME SALARY\n");
  323.  
  324. mioHashFile = fopen("emp", "r");
  325. fscanf (mioHashFile,"%d",&mnOverlowRecords);
  326. fseek (mioHashFile, mnHeaderSize, 0); //Skip past the CRLF at end of overflow counter
  327.  
  328. /* sequentially print all active records */
  329. for(int i=0;i<10+mnOverlowRecords;i++)
  330. {
  331. fscanf(mioHashFile,"%d%s%s%f",&nDeleteSwitch,sSSN,sName,&nSalary);
  332. if (nDeleteSwitch==0)printf("%-11s%-21s%-10.2f\n",sSSN,sName,nSalary);
  333. }
  334. fclose(mioHashFile);
  335. printf("Print Table Complete\n");
  336. return;
  337.  
  338. }
  339. // This function is used to Fold the entered SSN
  340. int AddDigits(char * psSSN)
  341. {
  342. int nSSN = 0;
  343. for ( int nChar = 0; psSSN[nChar]!=0 ; nChar++)
  344. {
  345. nSSN = nSSN + psSSN[nChar];
  346. }
  347. return nSSN;
  348. }
  349.  
  350.  
  351.  
  352.  
  353.  
Compilation error #stdin compilation error #stdout 0s 0KB
stdin
Standard input is empty
compilation info
prog.cpp: In function ‘void Insert()’:
prog.cpp:137:46: error: ‘strcmp’ was not declared in this scope
  if (nDeleteSwitch == 0 && strcmp(sInSSN,sSSN)==0)
                                              ^
prog.cpp:158:47: error: ‘strcmp’ was not declared in this scope
   if (nDeleteSwitch == 0 && strcmp(sInSSN,sSSN)==0)
                                               ^
prog.cpp: In function ‘FILE* find(char*)’:
prog.cpp:235:46: error: ‘strcmp’ was not declared in this scope
  if (nDeleteSwitch == 0 && (strcmp(psSSN,sSSN) == 0))  
                                              ^
prog.cpp:249:48: error: ‘strcmp’ was not declared in this scope
   if (nDeleteSwitch == 0 && (strcmp (psSSN,sSSN) == 0))  /* record found, return 
                                                ^
stdout
Standard output is empty