简体   繁体   中英

Caesar cipher in C++

To start off, I'm four weeks into a C++ course and I don't even know loops yet, so please speak baby talk?

Okay, so I'm supposed to read a twelve character string (plus NULL makes thirteen) from a file, and then shift the letters backwards three, and then print my results to screen and file. I'm okay with everything except the shifting letters. I don't want to write miles of code to take each character individually, subtract three, and re-assemble the string, but I'm not sure how to work with the whole string at once. Can someone recommend a really simple method of doing this?

If you are dealing with simple letters (A to Z or a to z), then you can assume that the internals codes are linear.

Letters are coded as numbers, between 0 and 127. A is coded as 65, B as 66, C as 67, Z as 90.

In order to shift letters, you just have to change the internal letter code as if it were a number, so basically just substracting 3 from the character. Beware of edge cases though, because substracting 3 to 'A' will give you '>' (code 62) and not 'X' (code 88). You can deal with them using "if" statements or the modulo operator ("%").

Here is an ASCII characters table to help you

Once you've loaded your string in, you can use the modulous operator to rotate while keeping within the confines of AZ space.

I'd keep track of whether the letter was a capital to start with:

bool isCaps = ( letter >= 'A' ) && ( letter <= 'Z' );
if( isCaps )
  letter -= 'A'-'a';

and then just do the cipher shift like this:

int shift = -3;
letter -= 'a'; // to make it a number from 0-25
letter = ( letter + shift + 26 ) % 26;
        // add 26 in case the shift is negative
letter += 'a'; // back to ascii code

finally finish off with

if( isCaps )
  letter += 'A'-'a';

so, putting all this together we get:

char *mystring; // ciphertext
int shift = -3; // ciphershift

for( char *letter = mystring; letter; ++letter )
{
  bool isCaps = ( *letter >= 'A' ) && ( *letter <= 'Z' );
  if( isCaps )
    *letter -= 'A'-'a';

  letter -= 'a';
  letter = ( letter + shift + 26 ) % 26;
  letter += 'a';

  if( isCaps )
    letter += 'A'-'a';
}

You're going to have to learn loops. They will allow you to repeat some code over the characters of a string, which is exactly what you need here. You'll keep an integer variable that will be your index into the string, and inside the loop do your letter-shifting on the character at that index and increment the index variable by one until you reach NULL.

Edit: If you're not expected to know about loops yet in your course, maybe they want you to do this:

string[0] -= 3; // this is short for "string[0] = string[0] - 3;"
string[1] -= 3;
string[2] -= 3;
...

It will only result in 12 lines of code rather than miles. You don't have to "reassemble" the string this way, you can just edit each character in-place. Then I bet after making you do that, they'll show you the fast way of doing it using loops.

Iterate over the characters with a for loop. And do what you want with the char*. Then put the new char back.

for(int i=0; i<12; i++){
  string[i] = string[i] - 3;
}

Where string is your character array (string). There is a bit more involved if you want to make it periodic (IE have A wrap round to Z, but the above code should help you get started)

I'm a little unclear what you mean by "shift the letters backwards 3"? Does that mean D ==> A?
If so, here's a simple loop.

(I didn't do reading from the file, or writing to the file... Thats your part)

#include <string.h>

int main(void)
{                      
    char input[13] = "ABCDEFGHIJKL";
    int i;

    int len = strlen(input);

    for(i=0; i<len; ++i)
    {
        input[i] = input[i]-3;
    }

    printf("%s", input);  // OUTPUT is: ">?@ABCDEFGHI"
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM