principlecppMinor
Java vs C++ (JAVAC)
Viewed 0 times
javacjavastackoverflow
Problem
Here's the problem for Java vs C++ (JAVAC):
Java and C++ use different naming conventions:
Examples of a Java identifier are: javaIdentifier, longAndMnemonicIdentifier, name, nEERC.
Examples of C++ identifiers are: c_identifier, long_and_mnemonic_identifier, name
Note: When identifiers consist a single word then Java and C++ naming conventions are identical:
You are writing a translator that is intended to translate C++ programs to Java and vice versa. Of course, identifiers in the translated program must be formatted due to its language naming conventions — otherwise people will never like your translator.
The first thing you would like to write is an identifier translation routine. Given an identifier, it would detect whether it is Java identifier or C++ identifier and translate it to another dialect. If it is neither, then your routine should report an error. Translation must preserve the order of words and must only change the case of letters and/or add/remove underscores.
How can I improve this code? How can I make it faster? Are there better solutions?
Java and C++ use different naming conventions:
- In Java a multiword identifier is constructed in the following manner:
- The first word is written starting from the small letter, and the following ones are written starting from the capital letter, no separators are used. All other letters are small.
Examples of a Java identifier are: javaIdentifier, longAndMnemonicIdentifier, name, nEERC.
- In C++ a multiword identifier is constructed in the following manner:
- Use only small letters in their identifiers. To separate words they use underscore character ‘_’.
Examples of C++ identifiers are: c_identifier, long_and_mnemonic_identifier, name
Note: When identifiers consist a single word then Java and C++ naming conventions are identical:
You are writing a translator that is intended to translate C++ programs to Java and vice versa. Of course, identifiers in the translated program must be formatted due to its language naming conventions — otherwise people will never like your translator.
The first thing you would like to write is an identifier translation routine. Given an identifier, it would detect whether it is Java identifier or C++ identifier and translate it to another dialect. If it is neither, then your routine should report an error. Translation must preserve the order of words and must only change the case of letters and/or add/remove underscores.
How can I improve this code? How can I make it faster? Are there better solutions?
#include
#include
#include
std::string convert(const std::string& s) {
std::string result{};
bool java = false;
bool cpp = false;
if (isupper(s[0]) || s[0] == '_' || s[s.size()-1] == '_') {
return "Error!";
}
for (std::size_t i = 0; i > str;
std::cout << convert(str) << '\n';
} while (std::cin);
}Solution
Input validation
The string literal
If you decide one day to change that text,
you'd have to remember to change everywhere,
which can be error prone.
It's better to turn string literals into global constants.
But actually returning
How will the caller know if the name was invalid?
The caller would have to know to compare returned values against the correct string literal used internally by the method.
It would be better to return an empty string instead,
which is easier for the caller to validate (instead of a full string comparison),
and document this fact in a comment above the function declaration.
Or you could take a non-const in/out parameter and return a boolean for success/failure. (Thanks @200_success!)
Add some test cases
It's good to add test cases with expected output,
so that if you want to refactor using different approaches there's an easy way to verify that everything still works.
For example:
These should all output 0. If you make any changes,
it's easy to verify by rerunning and looking for non-zero values in the output.
Simplify
The condition
Other things
I think it would make sense to reverse the logic of the
The current code sets
It would seem more intuitive to set
But maybe this is a matter of taste.
Lastly,
a minor thing,
I think it's more conventional to put a space after
The string literal
"Error!" is duplicated in multiple places.If you decide one day to change that text,
you'd have to remember to change everywhere,
which can be error prone.
It's better to turn string literals into global constants.
But actually returning
"Error!" is not a good way to handle invalid input.How will the caller know if the name was invalid?
The caller would have to know to compare returned values against the correct string literal used internally by the method.
It would be better to return an empty string instead,
which is easier for the caller to validate (instead of a full string comparison),
and document this fact in a comment above the function declaration.
Or you could take a non-const in/out parameter and return a boolean for success/failure. (Thanks @200_success!)
Add some test cases
It's good to add test cases with expected output,
so that if you want to refactor using different approaches there's an easy way to verify that everything still works.
For example:
std::cout << convert("javaIdentifier").compare("java_identifier") << "\n";
std::cout << convert("longAndMnemonicIdentifier").compare("long_and_mnemonic_identifier") << "\n";
std::cout << convert("name").compare("name") << "\n";
std::cout << convert("nEERC").compare("n_e_e_r_c") << "\n";
std::cout << convert("c_identifier").compare("cIdentifier") << "\n";
std::cout << convert("long_and_mnemonic_identifier").compare("longAndMnemonicIdentifier") << "\n";
std::cout << convert("n_e_e_r_c").compare("nEERC") << "\n";
std::cout << convert("!_e_e_r_c").compare("Error!") << "\n";
std::cout << convert("n_e_e_R_c").compare("Error!") << "\n";
std::cout << convert("n_e_e_r_c_").compare("Error!") << "\n";These should all output 0. If you make any changes,
it's easy to verify by rerunning and looking for non-zero values in the output.
Simplify
The condition
(java != cpp) || (!java && !cpp) can be simplified to !(java && cpp).Other things
I think it would make sense to reverse the logic of the
cpp and java variables.The current code sets
cpp to true when converting from java to cpp.It would seem more intuitive to set
cpp to true when cpp naming is detected.But maybe this is a matter of taste.
Lastly,
a minor thing,
I think it's more conventional to put a space after
#include, like this:#include
#include
#include Code Snippets
std::cout << convert("javaIdentifier").compare("java_identifier") << "\n";
std::cout << convert("longAndMnemonicIdentifier").compare("long_and_mnemonic_identifier") << "\n";
std::cout << convert("name").compare("name") << "\n";
std::cout << convert("nEERC").compare("n_e_e_r_c") << "\n";
std::cout << convert("c_identifier").compare("cIdentifier") << "\n";
std::cout << convert("long_and_mnemonic_identifier").compare("longAndMnemonicIdentifier") << "\n";
std::cout << convert("n_e_e_r_c").compare("nEERC") << "\n";
std::cout << convert("!_e_e_r_c").compare("Error!") << "\n";
std::cout << convert("n_e_e_R_c").compare("Error!") << "\n";
std::cout << convert("n_e_e_r_c_").compare("Error!") << "\n";#include <iostream>
#include <string>
#include <cctype>Context
StackExchange Code Review Q#77228, answer score: 6
Revisions (0)
No revisions yet.