tRot
tRot

Reputation: 75

Iterations of while loop returns strange values

I have two questions:

Assume the characters entered by the user in input are all contained in alphabet:

  1. If my input starts with "A", the first character in my output is "A", but if I start with any other character in alphabet, the output is the original character shifted to the right by 3. If my input starts with "A", why does my output also start at "A" and not at "D"?

  2. If my input is a string that has spaces (e.g. "Stack Overflow"), why is the first word the only component of my output? (How is the computer interpreting this?) I understand C++ considers new lines, spaces, and tabs to be whitespace, but I thought if the space was in a string, it would be treated as a character. How can I modify my code so the space and the rest of my input is included (preferably shifted) in my output?

using namespace std;

string alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz @#$%^&*()";   //a 62 character string
string input, output;
int shift = 3, index = 0;

cin >> input;

while(index < input.length()){
   if(alphabet.find(input[index]) != NULL){
       output += alphabet[(alphabet.find(input[index]) + shift) % 62];
   }
   index++;
}

Upvotes: 0

Views: 37

Answers (1)

Remy Lebeau
Remy Lebeau

Reputation: 595412

If my input starts with "A", the first character in my output is "A", but if I start with any other character in alphabet, the output is the original character shifted to the right by 3. If my input starts with "A", why does my output also start at "A" and not at "D"?

It doesn't. It skips the "A" and does not add it to the output at all!

This is because std::string::find() DOES NOT return a pointer, it returns an index. If it does not find a match, it returns std::string::npos (-1). Comparing NULL to an index treats the NULL as index 0. So, when find() does find "A", it returns 0, which you then compare as equal to NULL (0) and thus skip adding "D" to the output. All of the other input characters make find() return indexes other than 0, so they don't compare equal to NULL and so you shift all of them (including ones that cause find() to return npos, you shift all of those to index 2).

If my input is a string that has spaces (e.g. "Stack Overflow"), why is the first word the only component of my output? (How is the computer interpreting this?) I understand C++ considers new lines, spaces, and tabs to be whitespace, but I thought if the space was in a string, it would be treated as a character. How can I modify my code so the space and the rest of my input is included (preferably shifted) in my output?

operator>> reads whitespace-delimited words. It first skips leading whitespace (unless std::noskipws is used), and then it reads until it encounters whitespace. To read a string with spaces in it, use std::getline() instead.

With that said, try this instead:

using namespace std;

const string alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz @#$%^&*()";   //a 62 character string
string input, output;
const int shift = 3;

getline(cin, input);

for (string::size_type index = 0; index < input.length(); ++index) {
   string::size_type found_index = alphabet.find(input[index]);
   if (found_index != string::npos) {
       output += alphabet[(found_index + shift) % alphabet.size()];
   }
}

/*
Or, using C++11 or later:

for (char c : input) {
   auto found_index = alphabet.find(c);
   ... (same as above) ...
}

*/

Also, how does one format variables when asking questions on StackOverflow so that they're in little code blocks within writing a question? I see that on other people's posts, but I don't know how to do it, and it makes things far more readable.

Blocks of code can be indented by 4 spaces. The toolbar on StackOverflow's editor has a button for formatting code blocks. Just select the code and press the button.

Code inline of other text can be wrapped in `` quotes.

Click on the ? button on the right side of the editor's toolbar to see the supported formatting markup.

Upvotes: 1

Related Questions