// // Program: temperature_records. // // Purpose: Compare yesterday's high and low temperatures with // record highs and lows for that date; update records if necessary. // // Input: // From standard input, yesterday's date, high and low temperatures. // In text file temps_in.txt, record highs and lows for all dates. // (Each line contains month, day, record high, year of record // high, record low, year of record low.) // Output: // To standard output, record high/low for yesterday's high/low. // Updated master file in temps_out.txt. // #include #include // has ifstream, ofstream. #include // has exit(), EXIT_SUCCESS, EXIT_FAILURE // Function prototypes (see comments below). void openFiles(ifstream & in, ofstream & out); void closeFiles(ifstream & in, ofstream & out); void getUserInput(int & month, int & day, int & year, int & high, int & low); bool validateDate(int month, int day, int year); bool readMaster(ifstream & masterIn, int & month, int & day, int & high, int & highYear, int & low, int & lowYear); void writeMaster(ofstream & masterOut, int month, int day, int high, int highYear, int low, int lowYear); void doLow(int yesterdayLow, int yesterdayYear, int & low, int & lowYear); void doHigh(int yesterdayHigh, int yesterdayYear, int & high, int & highYear); // Main program. int main(void) { int yesterdayMonth, yesterdayDay, yesterdayYear; int yesterdayHigh, yesterdayLow; ifstream masterIn; ofstream masterOut; int month, day, high, highYear, low, lowYear; getUserInput(yesterdayMonth, yesterdayDay, yesterdayYear, yesterdayHigh, yesterdayLow); openFiles(masterIn, masterOut); // Copy records from input master to output master until we reach // yesterday's date. while (readMaster(masterIn, month, day, high, highYear, low, lowYear) && (month != yesterdayMonth || day != yesterdayDay)) writeMaster(masterOut, month, day, high, highYear, low, lowYear); // If we didn't find anything in master, bail. if (masterIn.eof()) { cout << "Error: No record found in master file.\n"; closeFiles(masterIn, masterOut); exit(EXIT_FAILURE); } // Compare yesterday's temps to records; update records if // necessary. doLow(yesterdayLow, yesterdayYear, low, lowYear); doHigh(yesterdayHigh, yesterdayYear, high, highYear); // Write out updated master record. writeMaster(masterOut, month, day, high, highYear, low, lowYear); // Copy remainder of master file. while (readMaster(masterIn, month, day, high, highYear, low, lowYear)) writeMaster(masterOut, month, day, high, highYear, low, lowYear); closeFiles(masterIn, masterOut); return EXIT_SUCCESS; } // Post: input, output files opened successfully opened; or if // not possible, program exited. void openFiles(ifstream & in, ofstream & out) { in.open("temps_in.txt"); if (in.fail()) { cout << "Unable to open input file temps_in.txt.\n"; exit(EXIT_FAILURE); } out.open("temps_out.txt"); if (out.fail()) { cout << "Unable to open output file temps_out.txt.\n"; exit(EXIT_FAILURE); } return; } // Post: input, output files closed. void closeFiles(ifstream & in, ofstream & out) { in.close(); out.close(); return; } // Post: user prompted to enter desired info (yesterday's date // and temps); responses returned in parameters; // program exited if date not valid. void getUserInput(int & month, int & day, int & year, int & high, int & low) { cout << "Enter yesterday's month, day, and year " " (e.g., 3 1 2000 for March 1 2000):\n"; cin >> month >> day >> year; if (!validateDate(month, day, year)) { cout << "Not a valid date!\n"; exit(EXIT_FAILURE); } cout << "Enter high, low temperatures (integer values):\n"; cin >> high >> low; return; } // Pre: month, day, year supposedly represent a date. // Post: returns true if they do, false if not. bool validateDate(int month, int day, int year) { if (year < 0) return false; if (month < 1 || month > 12) return false; int daysInMonth; if (month == 2) { if ((year%400 == 0) || ( year%4 == 0 && year%100 != 0)) daysInMonth = 29; else daysInMonth = 28; } else if (month == 9 || month == 4 || month == 6 || month == 11) daysInMonth = 30; else daysInMonth = 31; if (day < 1 || day > daysInMonth) return false; return true; } // Pre: masterIn successfully opened; file is in format described // in header comments. // Post: if masterIn is not at EOF, remaining variables contain // information from one line of file and return value is // true; else return value is false. bool readMaster(ifstream & masterIn, int & month, int & day, int & high, int & highYear, int & low, int & lowYear) { return (masterIn >> month >> day >> high >> highYear >> low >> lowYear); } // Pre: masterOut successfully opened. // Post: information from parameters has been written to masterOut, // in format described in header comments. void writeMaster(ofstream & masterOut, int month, int day, int high, int highYear, int low, int lowYear) { masterOut << month << " " << day << " " << high << " " << highYear << " " << low << " " << lowYear << endl; return; } // Pre: yesterdayLow, yesterdayYear represent yesterday's low temperature, // year; low, lowYear represent record low not including yesterday's // year. // Post: low, lowYear represent record low including yesterday's // year. // record low and year written to standard output. void doLow(int yesterdayLow, int yesterdayYear, int & low, int & lowYear) { if (yesterdayLow > low) { cout << "Record low for that date: " << low << ", set in " << lowYear << endl; } else { cout << "Yesterday's low is a new record!\n"; cout << "Previous record low for that date: " << low << ", set in " << lowYear << endl; low = yesterdayLow; lowYear = yesterdayYear; } return; } // Pre: yesterdayHigh, yesterdayYear represent yesterday's high temperature, // year; high, highYear represent record high not including yesterday's // year. // Post: high, highYear represent record high including yesterday's // year. // record high and year written to standard output. void doHigh(int yesterdayHigh, int yesterdayYear, int & high, int & highYear) { if (yesterdayHigh < high) { cout << "Record high for that date: " << high << ", set in " << highYear << endl; } else { cout << "Yesterday's high is a new record!\n"; cout << "Previous record high for that date: " << high << ", set in " << highYear << endl; high = yesterdayHigh; highYear = yesterdayYear; } return; }