Problem C
Notable Quotables
Programmers often want to put quotation marks inside quote-delimited string literals (we’ll just call them ‘strings’) in programs they write. However, since in C/C++ the double-quote character is used to begin and end strings, you have to escape the string delimiting characters that occur inside the string, like this:
char *x = "Then she said, \"Whatever shall we do?\"";
All this escaping can be a pain when the programmer has a lot of string delimiters that he/she wants to use in strings. Some programming languages like Perl allow the programmer to get around this problem by defining their own string delimiter, to replace the typical double-quote. We’ll build on that idea in this problem.
Your job is to write a converter for input from a made-up programming language that allows strings to be delimited in a way that they have no escaped delimiters. For each string, this conversion is always possible.
For instance, if the string contains no double-quotes, then it can be delimited by double-quotes. If the string has an escaped delimiter (i.e. the character used to delimit the string also occurs in the string and is escaped), then change the delimiting character to be one which does not occur in the string, so that no escaped delimiters are necessary to write the string.
Input
Input is a code listing of up to $10\, 000$ lines, each line at most $100$ characters long, ending at end of file. Each string in the code is delimited in one of the following ways (each example below includes an escaped version of the delimiter):
-
with double quotes, e.g. "What does \"yare\" mean?", or
-
with single quotes, e.g. 'No really, what does \'yare\' mean?', or
-
starting with the sequence Q=x, where indicates that x is the delimiting character for the following quote, which begins immediately and ends at the first occurance of x that is not escaped, e.g. Q=!What does "yare" mean\!!. There is no break (e.g. newline) separating the three characters Q=x.
Strings may start anywhere in the code, all strings are properly closed, and strings are not nested. A string may contain escaped delimiters, which start with a backslash followed by the delimiter. Strings may also include other escaped characters, such as ‘\n’, or ‘\\’ (an escaped backslash), but escaped characters do not occur outside strings. Strings may span multiple lines. Only the following characters may be used as delimiters: ", ’, !, @, #, $, %, ^, &, *, a–z, and A–Z. Other than that, the code may contain any ASCII code $32$ (space) to $126$ (tilde), as well as newlines. However, no string contains all possible delimiters.
Output
Output the original code, with possibly-modified string delimiters so that no string has any escaped delimiters. Other escaped characters remain escaped.
The order of preference for changed quote delimiters is ", ’, !, @, #, $, %, ^, &, *, followed by the lowercase alphabet (a–z), followed by the uppercase alphabet (A–Z).
Sample Input 1 | Sample Output 1 |
---|---|
#include <iostream> using namespace std; char *messages[] = { "\"You could not possibly have come at a better time, my dear Watson,\"", Q=#he said cordially.#, "\"I was afraid that you were 'engaged'.\"", Q=^"So I am. Very much so."^, }; int main() { cout << "'The Adventures of Sherlock Holmes', by \"Sir Arthur Conan Doyle\"!\n"; for (int i = 0; i < 8; i++) cout << messages[i] << endl; return 0; } |
#include <iostream> using namespace std; char *messages[] = { '"You could not possibly have come at a better time, my dear Watson,"', "he said cordially.", Q=!"I was afraid that you were 'engaged'."!, '"So I am. Very much so."', }; int main() { cout << Q=@'The Adventures of Sherlock Holmes', by "Sir Arthur Conan Doyle"!\n@; for (int i = 0; i < 8; i++) cout << messages[i] << endl; return 0; } |