/* * This program decompresses a file produced by wordcomp. It takes as input * a file produced by that program, and outputs the file wordcomp read. */ #include #include #include #include #include using std::string; const int CUTOFF = 3; /* * Read the next unit from standard input. Units are alnum, or non-alnum, * or starting with one of the marker characters, @ or #. */ std::string read_next(std::istream &strm) { // Read the first character. If none, we're done. char firstch; if(!strm.get(firstch)) return ""; // Result string. Starts with that first character. string ret; ret.push_back(firstch); // If we see an @, it is the first of pair which needs to be // translated. if(firstch == '@') { // Read the second character. If it's not there, we'll call // it over. char secondch; if(!strm.get(secondch)) return ""; ret.push_back(secondch); return ret; } // If we see a #, we need to read the digits. We allow for the # to // be the last character, which would be an error in the input. if(firstch == '#') { // What we got? Read digits int nextch; while((nextch = strm.peek()) != EOF) { if(isdigit(nextch)) ret.push_back(strm.get()); else break; } return ret.size() > 1 ? ret : ""; } // Now, use the istream peek() method to add all immediately following // characters of the same class, up to a marker character. int nextch; bool should_be_alnum = isalnum(firstch); while((nextch = strm.peek()) != EOF) { if(nextch == '@' || nextch == '#') break; else if(should_be_alnum == (bool)isalnum(nextch)) ret.push_back(strm.get()); else break; } return ret; } int main() { // Numeric substitutions std::vector numsub; // Letter substitutions std::vector charsub; string word; while((word = read_next(std::cin)) != "") { if(word[0] == '@') { // Translate. std::cout << charsub[word[1] - '!']; } else if(word[0] == '#') { // Translate. std::cout << numsub[std::stoi(word.substr(1))]; } else if(isalnum(word[0])) { // Record. if(word.length() > CUTOFF) { // Record a long word with an integer. numsub.push_back(word); } else if(word.length() == CUTOFF) { // Record a short word with a letter. if('!' + charsub.size() <= '~') { charsub.push_back(word); } } std::cout << word; } else { // Output std::cout << word; } } }