-2

Yesterday I started developing a encrypting machine, that works like a Caesar cipher. You put a message (e.g., HELLO), choose a key value (e.g., 3) and the result is KHOOR (3 letters forward).
The problem is that, if I use "cin >> msg;" I can only codify one word. If I use "getline (cin, msg);", the code doesn't work. Maybe it's a simple problem, but I can't solve it... :(

string msg;
int a, b, i, key_value;
char c;

cout << "WRITE YOUR MESSAGE:" << endl;
cin >> msg;                         //HERE IS THE PROBLEM!!!

system ("cls");

cout << "PUT A KEY VALUE:" << endl;
cin >> key_value;

system ("cls");

cout << "THE CODIFIED MESSAGE IS:" << endl;

for (i=0; i < msg.length(); i++) {

    if (msg[i] == 'A') a = 1;
    if (msg[i] == 'B') a = 2;
    if (msg[i] == 'C') a = 3;
    if (msg[i] == 'D') a = 4;
    if (msg[i] == 'E') a = 5;
    if (msg[i] == 'F') a = 6;
    if (msg[i] == 'G') a = 7;
    if (msg[i] == 'H') a = 8;
    if (msg[i] == 'I') a = 9;
    if (msg[i] == 'J') a = 10;
    if (msg[i] == 'K') a = 11;
    if (msg[i] == 'L') a = 12;
    if (msg[i] == 'M') a = 13;
    if (msg[i] == 'N') a = 14;
    if (msg[i] == 'O') a = 15;
    if (msg[i] == 'P') a = 16;
    if (msg[i] == 'Q') a = 17;
    if (msg[i] == 'R') a = 18;
    if (msg[i] == 'S') a = 19;
    if (msg[i] == 'T') a = 20;
    if (msg[i] == 'U') a = 21;
    if (msg[i] == 'V') a = 22;
    if (msg[i] == 'W') a = 23;
    if (msg[i] == 'X') a = 24;
    if (msg[i] == 'Y') a = 25;
    if (msg[i] == 'Z') a = 26;

    b = a + key_value;

    if (b > 26) b -= 26;

    if (b == 1) c = 'A';
    if (b == 2) c = 'B';
    if (b == 3) c = 'C';
    if (b == 4) c = 'D';
    if (b == 5) c = 'E';
    if (b == 6) c = 'F';
    if (b == 7) c = 'G';
    if (b == 8) c = 'H';
    if (b == 9) c = 'I';
    if (b == 10) c = 'J';
    if (b == 11) c = 'K';
    if (b == 12) c = 'L';
    if (b == 13) c = 'M';
    if (b == 14) c = 'N';
    if (b == 15) c = 'O';
    if (b == 16) c = 'P';
    if (b == 17) c = 'Q';
    if (b == 18) c = 'R';
    if (b == 19) c = 'S';
    if (b == 20) c = 'T';
    if (b == 21) c = 'U';
    if (b == 22) c = 'V';
    if (b == 23) c = 'W';
    if (b == 24) c = 'X';
    if (b == 25) c = 'Y';
    if (b == 26) c = 'Z';

    cout << c;

}
xSoloDrop
  • 1
  • 2
  • 1
    Please post a [Minimal, Complete, and Verifiable example](http://stackoverflow.com/help/mcve). Possible duplicate (but too low possibility to vote) of [c++ - Why does std::getline() skip input after a formatted extraction? - Stack Overflow](http://stackoverflow.com/questions/21567291/why-does-stdgetline-skip-input-after-a-formatted-extraction) – MikeCAT Jul 13 '16 at 16:10
  • 7
    Please explain *the code doesn't work*. – lurker Jul 13 '16 at 16:11
  • 1
    Although this isn't related to your question (for which I agree with @MikeCAT), the way that you're handling the conversion of a number to its letter in the alphabet leaves a lot to be desired, and makes your code very annoying to read. See this question for a better strategy: http://stackoverflow.com/questions/9259140/converting-numbers-into-alphabets-in-c – Jake Jul 13 '16 at 16:13
  • What happens if every comparison in the first set is false? What happens if the first character in the string isn't an upper case letter? Also, any time you find you're writing a chunk of "cut&paste" code, stop and see if you can replace the bulky redundant code with an algorithm. (Also, why use 1-26 rather than 0-25, which would allow you to use modulus.) – David Schwartz Jul 13 '16 at 16:13
  • When I try to run the code with getline() it ends instantly. I can't write anything. – xSoloDrop Jul 13 '16 at 16:15
  • @xSoloDrop do you have another input in your program before that line? – Slava Jul 13 '16 at 16:17
  • @xSoloDrop That's almost certainly because of prior code that you haven't shown us. For example, if you have `cin >> x; getline(cin,msg);` you'll get an empty line because `cin >> x;` doesn't read the newline, leaving an empty line for `getline` to read. If someone types `foobar` and you read just the `foo`, you then have an empty line followed by `bar`. You need some code to read that newline or `getline` will get it. – David Schwartz Jul 13 '16 at 16:17
  • You havent even shown how you use `getline`, how can we help you? – Fantastic Mr Fox Jul 13 '16 at 16:17

2 Answers2

1

So your code works fine: http://ideone.com/lBhD78

If you're trying to accept more than 1 word the simple extraction operator will not work however. Which is probably what you're asking about. In this case you will want to use getline. Like this for instance:

getline(cin, msg, '\n');

So I'm not certain what you're complaining about, however this could be much improved by:

  1. Being case-insensitive
  2. Only modifying alpha-characters

You could accomplish this by doing something like:

transform(cbegin(msg), cend(msg), ostream_iterator<char>(cout), [&](unsigned char i){
    if(isalpha(i)) {
        const auto a = islower(i) ? 'a' : 'A';

        i = (i - a + key_value) % 26 + a;
    }
    return i; });

I've written a Live Example complete with getline.

Jonathan Mee
  • 35,107
  • 16
  • 95
  • 241
  • 1
    ...providing your host character set encodes alphabetic characters sequentially (ASCII-like codes do; ECBDIC codes don't; C++ doesn't guarantee anything). – Toby Speight Jul 13 '16 at 16:57
  • @TobySpeight It's true there is nothing guaranteed about `char`s being ASCII or UTF-8, but then I guess there's nothing guaranteed about there being 26 characters in the alphabet either :/ Anyway I've fixed it so that the a `char` won't be overflowed. (But I haven't fixed the 26 it's just example code after all.) – Jonathan Mee Jul 13 '16 at 17:52
0

You have to be carefull to write questions. BUT, without being clear what you mean, the answer is:

  • When you read cin>>s, by default, you are considering the data are separated by "white spaces". So, it skips spaces and read the string until a new space or end of input.
  • If you have problems with getline, probably the problem is before the code you are shown. If you read a value with, for example, cin>>integer, you push newline key at the end of the input, but this character is still in the stream. If the following line in your code es getline, probably you will read an empty line.

In the first item you find why you current code works, in the second one, why your getline-version doesn't.

EFenix
  • 831
  • 4
  • 11