random.cpp 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  1. // random.cpp -- random access to a binary file
  2. #include <iostream> // not required by most systems
  3. #include <fstream>
  4. #include <iomanip>
  5. #include <cstdlib> // (or stdlib.h) for exit()
  6. const int LIM = 20;
  7. struct planet
  8. {
  9. char name[LIM]; // name of planet
  10. double population; // its population
  11. double g; // its acceleration of gravity
  12. };
  13. const char * file = "planets.dat"; // ASSUMED TO EXIST (binary.cpp example)
  14. inline void eatline() { while (std::cin.get() != '\n') continue; }
  15. int main()
  16. {
  17. using namespace std;
  18. planet pl;
  19. cout << fixed;
  20. // show initial contents
  21. fstream finout; // read and write streams
  22. finout.open(file,
  23. ios_base::in | ios_base::out | ios_base::binary);
  24. //NOTE: Some Unix systems require omitting | ios::binary
  25. int ct = 0;
  26. if (finout.is_open())
  27. {
  28. finout.seekg(0); // go to beginning
  29. cout << "Here are the current contents of the "
  30. << file << " file:\n";
  31. while (finout.read((char *) &pl, sizeof pl))
  32. {
  33. cout << ct++ << ": " << setw(LIM) << pl.name << ": "
  34. << setprecision(0) << setw(12) << pl.population
  35. << setprecision(2) << setw(6) << pl.g << endl;
  36. }
  37. if (finout.eof())
  38. finout.clear(); // clear eof flag
  39. else
  40. {
  41. cerr << "Error in reading " << file << ".\n";
  42. exit(EXIT_FAILURE);
  43. }
  44. }
  45. else
  46. {
  47. cerr << file << " could not be opened -- bye.\n";
  48. exit(EXIT_FAILURE);
  49. }
  50. // change a record
  51. cout << "Enter the record number you wish to change: ";
  52. long rec;
  53. cin >> rec;
  54. eatline(); // get rid of newline
  55. if (rec < 0 || rec >= ct)
  56. {
  57. cerr << "Invalid record number -- bye\n";
  58. exit(EXIT_FAILURE);
  59. }
  60. streampos place = rec * sizeof pl; // convert to streampos type
  61. finout.seekg(place); // random access
  62. if (finout.fail())
  63. {
  64. cerr << "Error on attempted seek\n";
  65. exit(EXIT_FAILURE);
  66. }
  67. finout.read((char *) &pl, sizeof pl);
  68. cout << "Your selection:\n";
  69. cout << rec << ": " << setw(LIM) << pl.name << ": "
  70. << setprecision(0) << setw(12) << pl.population
  71. << setprecision(2) << setw(6) << pl.g << endl;
  72. if (finout.eof())
  73. finout.clear(); // clear eof flag
  74. cout << "Enter planet name: ";
  75. cin.get(pl.name, LIM);
  76. eatline();
  77. cout << "Enter planetary population: ";
  78. cin >> pl.population;
  79. cout << "Enter planet's acceleration of gravity: ";
  80. cin >> pl.g;
  81. finout.seekp(place); // go back
  82. finout.write((char *) &pl, sizeof pl) << flush;
  83. if (finout.fail())
  84. {
  85. cerr << "Error on attempted write\n";
  86. exit(EXIT_FAILURE);
  87. }
  88. // show revised file
  89. ct = 0;
  90. finout.seekg(0); // go to beginning of file
  91. cout << "Here are the new contents of the " << file
  92. << " file:\n";
  93. while (finout.read((char *) &pl, sizeof pl))
  94. {
  95. cout << ct++ << ": " << setw(LIM) << pl.name << ": "
  96. << setprecision(0) << setw(12) << pl.population
  97. << setprecision(2) << setw(6) << pl.g << endl;
  98. }
  99. finout.close();
  100. cout << "Done.\n";
  101. // keeping output window open
  102. // cin.clear();
  103. // eatline();
  104. // cin.get();
  105. return 0;
  106. }