#include #include #include #include #define DATA_FILENAME "data.txt" #define ROOT 5 #define BASE 10 #define REVERSE_FILE_ROOT_5 "out/immortal_number_%d_root5_base10.txt" #define REVERSE_FILE_ROOT_6 "out/immortal_number_%d_root6_base10.txt" // ------------------------------------------------------------------------------------------------------ static inline void mygetline(std::string* line, std::ifstream* myfile) { /* if (myfile.good()) return null; */ if (myfile->eof()) { *line = ""; return; } std::getline(*myfile, *line); if (line->size() == 0) return; if (line->at(line->size() - 1) == '\r') { line->resize(line->size() - 1); } } int main(void) { #define SIGNATURE "Immortal Number Report File Version 3.00" #define END_SIG "END OF REPORT" /*unsigned*/ char* a; unsigned /* long long */ int a_size = 0; unsigned /* long long */ int top = -1; // u unsigned /* long long */ int digits = -1; // u+1 bool a_empty; std::string line; std::ifstream myfile(DATA_FILENAME); if (myfile.is_open()) { // __try { top = -1; digits = -1; mygetline(&line, &myfile); if (strcmp(line.c_str(), SIGNATURE) != 0 /* not equal */) { std::cerr << "Load error: Wrong format signature. Expecting '" << SIGNATURE << "'." << std::endl; myfile.close(); return EXIT_FAILURE; } mygetline(&line, &myfile); // Minor. signature mygetline(&line, &myfile); // "" mygetline(&line, &myfile); // "(Starting time)" mygetline(&line, &myfile); mygetline(&line, &myfile); // "" mygetline(&line, &myfile); // "(Save timestamp)" mygetline(&line, &myfile); // Timestamp mygetline(&line, &myfile); // "" mygetline(&line, &myfile); // "(Base)" mygetline(&line, &myfile); // 10 unsigned int base = atoi(line.c_str()); if (base != BASE) { std::cerr << "This edition can only work with base = " << BASE << "." << std::endl; myfile.close(); return EXIT_FAILURE; } mygetline(&line, &myfile); // "" mygetline(&line, &myfile); // "(Root)" mygetline(&line, &myfile); // 5 unsigned int root = atoi(line.c_str()); if (root != ROOT) { std::cerr << "This edition can only work with root = " << ROOT << "." << std::endl; myfile.close(); return EXIT_FAILURE; } mygetline(&line, &myfile); // "" mygetline(&line, &myfile); // "(Digits)" mygetline(&line, &myfile); digits = atoi(line.c_str()); mygetline(&line, &myfile); // "" mygetline(&line, &myfile); // "(r)" mygetline(&line, &myfile); mygetline(&line, &myfile); // "" a_size = digits; a = (/*unsigned*/ char*) calloc(a_size, sizeof(/*unsigned*/ char)); if (a == NULL) { std::cerr << "Memory allocation failed!" << std::endl; myfile.close(); return EXIT_FAILURE; } mygetline(&line, &myfile); // "(Reversed notation)" do { mygetline(&line, &myfile); for (unsigned int i = 0; i < line.length(); ++i) { /*unsigned*/ char toadd = line.c_str()[i] - '0'; if (digits == top + 1) { std::cerr << "Corrupt: Formal and actual length mismatch!" << std::endl; myfile.close(); return EXIT_FAILURE; } // Cannot overflow if input file is OK. a[++top] = toadd; a_empty = false; } } while (strcmp(line.c_str(), "") != 0 /* not equal */); if (digits != top + 1) { std::cerr << "Corrupt: Formal and actual length mismatch!" << std::endl; myfile.close(); return EXIT_FAILURE; } mygetline(&line, &myfile); if (strcmp(line.c_str(), END_SIG) != 0 /* not equal */) { std::cerr << "Corrupt: End-signature mismatch." << std::endl; myfile.close(); return EXIT_FAILURE; } // } __finally { myfile.close(); // } } else { std::cerr << "Cannot open file!" << std::endl; return EXIT_FAILURE; } char fn[255]; // Base 5 sprintf(fn, REVERSE_FILE_ROOT_5, digits); std::ofstream outfile; outfile.open(fn, std::ios::out); // __try { for (int i = top; i >= 0; --i) { /*unsigned*/ char xa = a[i] + '0'; outfile << xa; } // } __finally { outfile.close(); // } // Base 6 (converted) sprintf(fn, REVERSE_FILE_ROOT_6, digits); outfile.open(fn, std::ios::out); // __try { for (int i = top; i >= 0; --i) { /*unsigned*/ char xa = a[i] + '0'; if (i == 0) xa = 11 - xa; else xa = 9 - xa; outfile << xa; } // } __finally { outfile.close(); // } free(a); return EXIT_SUCCESS; }