The Way to Programming
The Way to Programming
Reading from a binary file in C++
I am trying to write a program which display 10 records at a time from the binary quote file. Program starts by displaying the first 10 days from the quote file. The program takes a single character input and responds as follows:
“n” displays the next 10 days of quotes
“p” displays the previous 10 days of quotes
“b” resets the quote display to the first 10 days of the file
“e” display the last 10 days of the file
“q” exits the program
I need to make sure “n” and “p” do not attempt to read before the beginning or after the end of the file data.
This is how i solved the problem. for user input, ‘q’, ‘b’, and ‘e’ the program works fine. However, I am having program with implementing cases ‘p’ and ‘n’ and will be glad if annoy can help. The number of line in the binary file is 5101. Thanks in advance.
#include#include #include #include #include #include using namespace std; const int FLENGTH = 5101; // maximum length of file struct Quotes // structure for quote variables { char date[11]; // character strings to hold date from quotes double open; // variable to store open price double high; // variable to store high price double low; // variable to store low price double close; // variable to store close price long volume; // variable to store volume price double adjusted; // variable to store adjusted closed price }; char getchoice(); // function get which package customer is subscribed to void showRec(Quotes record); // function display quotes for a day int main() { Quotes spy; // create of quote struct char choice; // character for user input int current_pos = 0; // integer to tract current position ifstream inFile("spy.dat", ios::in | ios::binary); // open the spy.dat file in binary and read only mode if (!inFile) // check to see if file exist { cout << "Error opening file . Program aborting" << endl; return 0; } cout << "Displaying first 10 days of quote" << endl << endl; while (current_pos < 10) { inFile.seekg(current_pos * sizeof(spy), ios::beg); inFile.read(reinterpret_cast (&spy), sizeof(spy)); showRec(spy); current_pos++; } do { cout << endl; choice = getchoice(); cin.clear(); cout << endl; switch (choice) { case 'n': cout << "Displaying next 10 days of quote" << endl << endl; current_pos = 0; while (current_pos < 10) { if (!inFile.eof()) { inFile.seekg(sizeof(spy), ios::cur); inFile.read(reinterpret_cast (&spy), sizeof(spy)); showRec(spy); current_pos++; } else if (inFile.eof()) { cout << "\nCannot read beyond this point" << endl; cout << "Program is terminating\n" << endl; return 0; } } cout << endl; break; case 'p': cout << "Displaying previous 10 days of quote" << endl << endl; current_pos = 0; inFile.seekg(-10 * static_cast (sizeof(spy)), ios::cur); while (current_pos < 10) { inFile.seekg(sizeof(spy), ios::cur); inFile.read(reinterpret_cast (&spy), sizeof(spy)); showRec(spy); current_pos++; } cout << endl; break; case 'b': cout << "Resetting to first 10 days of quote" << endl << endl; inFile.seekg(0 * sizeof(spy), ios::beg); current_pos = 0; while (current_pos < 10) { inFile.read(reinterpret_cast (&spy), sizeof(spy)); showRec(spy); current_pos++; } cout << endl; break; case 'e': cout << "Displaying last 10 days of quote" << endl << endl; current_pos = 0; inFile.seekg(-10 * static_cast (sizeof(spy)), ios::end); while (!inFile.eof() && current_pos < 10) { inFile.read(reinterpret_cast (&spy), sizeof(spy)); showRec(spy); current_pos++; } cout << endl; break; } } while (choice != 'q'); cin.get(); return 0; } char getchoice() // function get which package customer is subscribed to // function to get package type { char choice; // get package type while (true) { cout << "Enter 'n' to display the next 10 days of quotes" << endl; cout << "Enter 'p' to display the previous 10 days of quotes" << endl; cout << "Enter 'b' to reset the quote display to the first 10 days of the file" << endl; cout << "Enter 'e' to display the last 10 days of the file" << endl; cout << "Enter 'q' to quit the program" << endl; cout << "Input Choice: " << flush; cin.get(choice); cin.clear(); // get the package type cout << endl; choice = tolower(choice); // convert package character to upper case if (choice == 'q') { cout << "Program is terminating" << endl; exit(1); } if ((cin.fail()) && (choice != 'n') && (choice != 'b') && (choice != 'p') && (choice != 'e')) { cin.clear(); // cin.clear() resets any error flags on the stream cin.ignore(numeric_limits ::max(), '\n'); // will flush the input stream of garbage cout << "\n" "Hey, that's not a valid input for the choice type!\n"; // prompting user for correct package cout << endl; } else // Return a a valid package { cin.ignore(numeric_limits ::max(), '\n'); break; } } return choice; } void showRec(Quotes spy) { cout << left << spy.date << right << setw(8) << fixed << setprecision(2) << spy.open << setw(10); cout << setw(10) << spy.high << setw(10) << spy.low << setw(10) << spy.close << setw(12) << spy.volume; cout << setw(10) << spy.adjusted << endl; }
What is the actual structure of the binary file? Because your definition of “Quotes” is odd. First of all, you have an 11-byte date char array. Yet the actual space taken by it will be 16 bytes, since it is followed by a double and by default compiler aligns doubles to a multiple of 8 offset. Another problem is that you use “long” type in your definition, which means that depending on the actual binary structure, it will work either only when compiled in x86 mode or in x64 mode, because long has a different size on those. Although it might still accidentally work due to the double after it being aligned to the same place anyway.
Sign in to your account