/* This program will decode a message. The code that is to be used is specified in a file named code.dat. Each line of this file contains information about the code for one character. This character is the first thing on the line. This is followed by a space, then the string that encodes that character. The message that is to be decoded in another file, named message.dat. This file contains code strings, separated by spaces and/or ends-of-line. The program reads the code strings one-by-one from this file and outputs the corresponding decoded chars to standard output. If an string is found in the message file that is not a legal code string, then a '?' is output and a message is printed at the end of the output. */ #include #include #include using namespace std; const int MAX_CODE_COUNT = 100; // Max number of chars allowed in the code. const int MAX_LINE_LENGTH = 70; // Max number of chars on a line of output. /* A CodeInfo struct contains information about the * code for one character. */ struct CodeInfo { char ch; // The character. string str; // The code string for that character. }; /* Reads the code from a file named "code.dat". This file must * be in the format described above. The code is stored in the * code parameter, and the number of chars in the code is stored * in codeCt. If there are more than MAX_CODE_COUNT codes in the * file, the extra codes will be silently ignored, and codeCt * will be equal to MAX_CODE_CODE. */ void readCode(CodeInfo code[], int &codeCt) { ifstream codeFile; codeFile.open("code.dat"); if (!codeFile) { cout << "*** Error: Cannot open code file \"code.dat\".\n"; cout << "*** Aborting.\n"; exit(1); } codeCt = 0; while (true) { // Read one line of data from the file. if (codeCt == MAX_CODE_COUNT) { // Have reached the maximum allowed number of codes. break; } codeFile.get(code[codeCt].ch); codeFile >> code[codeCt].str; if (!codeFile) { // End-of-file (or possible a read error). break; } codeFile.ignore(10000,'\n'); // Discard rest of this line. // The following line was used during development for error checking. // cout << code[codeCt].ch << " " << code[codeCt].str << endl codeCt++; } } // end readCode /* Searches the code array for a record in which the code string * string is str. If it is found, then ch is set equal to the * corresponding decoded character and the return value of the * function is true. A return value of false indicates that the * code string was not found. The third parameter is the array that * contains the codes, and the fourth parameter is the number of * codes in the array. */ bool decode(string str, char &ch, CodeInfo code[], int codeCt) { for (int i = 0; i < codeCt; i++) { if (code[i].str == str) { ch = code[i].ch; return true; } } return false; } // end decode int main() { CodeInfo code[MAX_CODE_COUNT]; // The code. int codeCt; // Number of items stored in the code array. readCode(code,codeCt); ifstream messageFile; // File containing the message to be decoded. string str; // One code string from the file. char ch; // The decoded character corresponding to str. int errorCt = 0; // Number of errors that have been found in the file. int charsOnLine = 0; // The number of characters on current output line. string word = ""; // Stores output chars until we come to a space. messageFile.open("message.dat"); if (!messageFile) { cout << "***Error: Can't open message file \"message.dat\".\n"; cout << "***Aborting.\n"; exit(1); } messageFile >> str; while (messageFile) { // Try to decode str, giving ch. If this fails, output a ? and // increase the error count. If there have been 100 errors, // assume that the file is bad and exit. if (decode(str,ch,code,codeCt) == false) { ch = '?'; errorCt++; if (errorCt == 100) { cout << "\n\n***Error: 100 errors found in input file.\n"; cout << "***Aborting.\n"; exit(1); } } // Add ch to the output; output an end-of-line if appropriate. // Non-blank chars are simply added to word. Output occurs when // a space is encountered. if (ch != ' ') { word += ch; } else { if (word.length() + charsOnLine >= MAX_LINE_LENGTH) { // Writing word on current line would exceed maximum line // length, so output an end-of-line and start a new line // before outputting the word. cout << endl; charsOnLine = 0; } cout << word << ' '; // Output the word and the space. charsOnLine = charsOnLine + word.length() + 1; word = ""; // Start a new word. } messageFile >> str; } cout << word << "\n"; // Output the last word and a final end-of-line. if (errorCt > 0) { cout << "\n*** " << errorCt << " unknown codes found in input file.\n"; cout << "*** These codes are represented by \"?\" in the output.\n"; } } // end main()