Search code examples
c++variablesswitch-statementcycle

How do I change the int variable in a cycle and if so is there a more efficient way?


First post ever on this site so spare my life , please. I'm trying to do a little encryption and decryption program imitating the Enigma cipher/machine from the WW2 (enough history lessons)

So I'm trying to input a number and a letter like so : 1h 2e 3l 4l 5o ; Because I don't use a cycle I need to write for every variable that I'm adding the number , but what do I do if I have less letters than variables?The only way I can think of is using a cycle which checks if the input is a letter or not.That's why the current code I've written only can be used for specific amount of numbers and letters...

#include <iostream>
#include <limits>
using namespace std;
int main()
{

int opt;
cout<<"Enter 1 for encryption and 2 for decryption. "<<endl;
cin>>opt;
if(opt == 1)
  {
  int setting1,setting2,setting3,setting4;
  char a,b,c,d;
  cout<<"_________________________________________________"<<endl;
  cin>>setting1>>a>>setting2>>b>>setting3>>c>>setting4>>d;
    a+=setting1;
    b+=setting2;
    c+=setting3;
    d+=setting4;
  cout<<(char)a<<" "<<(char)b<<" "<<(char)c<<" "<<(char)d<<endl;

  }
if(opt == 2)
  {
  int setting1,setting2,setting3,setting4;
  char a,b,c,d;
  cout<<"_________________________________________________"<<endl;
  cin>>setting1>>a>>setting2>>b>>setting3>>c>>setting4>>d;
    a-=setting1;
    b-=setting2;
    c-=setting3;
    d-=setting4;
  cout<<(char)a<<(char)b<<(char)c<<(char)d<<endl;

  }
  if(opt !=1 && opt !=2)cout<<"ERROR!"<<endl;



  std::cout << "Press ENTER to continue..."<<endl;
  std::cin.ignore( std::numeric_limits<std::streamsize>::max(),'\n');
  return 0;
} 

Also I was told that the last 2 lines would prevent the .exec from closing after it's done doing it's thing.


Solution

  • I recommend inputting your data in loops (cycles). But before that is accomplished, I suggest using a structure (or class) with an overloaded stream extraction operator.

    struct Number_Letter
    {
      int number;
      char letter;
      friend std::istream& operator>>(std::istream& inp, Number_Letter& nl);
    };
    std::istream& operator>>(std::istream& inp, Number_Letter& nl)
    {
      inp >> nl.number;
      if (inp)
      {
        inp >> nl.letter;
        if (!isalpha(nl.letter))
        {
          // Error recovery for not reading a letter
        }
      }
      else
      {
        // Error recovery for failing to read number.
      }
      return inp;
    }
    

    Your input loop would be something like:

    Number_Letter nl;
    while (std::cin >> nl)
    {
      // process the data
    }
    

    For cryptography, you may want to keep the data as a string:

    std::string message;
    getline(cin, message);
    for (unsigned int i = 0; i < message.length(); i += 2)
    {
      if (!isdigit(message[i]))
      {
        cerr << "Invalid message type at position " << i << endl;
        break;
      }
      if (i + 1 > message.length())
      {
        cerr << "Missing letter at end of message.\n";
        break;
      }
      if (!isalpha(message[i+1]))
      {
        cerr << "Invalid message type at position " << i << endl;
        break;
      }
    }