Loc Thien Tran
Loc Thien Tran

Reputation: 35

c++ caesar cipher program executes wrong character

Here is what I get when I try to encrypt "This is a test sentence!": "Ymnxp���p�����t�������"

I have tested my encryption part before and it worked fine.

Can anyone please tell me what did I do wrong here?

#include <iostream>
#include <string>
#include <fstream>
#include <stdlib.h>
#include <stdio.h>
#include "unistd.h"

using namespace std;


void displayUsage(){
    // Displays how to use this program
    // TODO
    cout << "Instruction: \n use -r to give rotation number \n use -f to give file name" <<endl;
}


int main(int argc, char **argv){

  string text;
  char* input_file_name;
  int rotation;
  bool have_rotation = false;
  bool have_input_file_name = false;


    // process command-line arguement
    int opt = 0;
    extern char *optarg;
    static const char* opt_string = "r:f:";
    opt = getopt( argc, argv, opt_string);
    while(opt != -1) // While there are parameters to parse, do so
    {  
        switch(opt)
        {
            case 'r':
                have_rotation = true;
                rotation = atoi(optarg);
                break;
            case 'f':
                have_input_file_name = true;
                input_file_name = optarg;
                break;
            default:
              displayUsage();
              return 1;
        }
        opt = getopt( argc, argv, opt_string);  // Pull the next parameter, or 0 if none.
    }

    if(!have_rotation)
    {
      displayUsage();
      return 0;
    }

    if(have_rotation)
    {
      if(have_input_file_name)
      {     
        ifstream file(input_file_name);
        string text2, temp;
        while(!file.eof())
        {
          getline(file, temp);
          text2 += temp;
          text2 += "\n";
        }
        text = text2[text2.size()-2];
      }
      else
      {
      cout <<"Enter text:"<<endl;
      cin >> text;
     }
    }

    char cipher[text.size()];

    for(int i=0; i<text.size(); i++)
    {
      cipher[i] = text[i];
      if(islower(cipher[i]))
      {
        cipher[i] = (cipher[i] - 'a' + rotation)%26 + 'a';
      }
      else if(isupper(cipher[i]))
      {
        cipher[i] = (cipher[i] - 'A' + rotation)%26 + 'A';
      }
    }

    cout <<cipher<<endl;

  return 0;
}

Upvotes: 0

Views: 144

Answers (2)

Loc Thien Tran
Loc Thien Tran

Reputation: 35

I can get my code run if I type the sentence manually. It doesn't printout anything if I input a text file.

#include <iostream>
#include <string>
#include <fstream>
#include <stdlib.h>
#include <stdio.h>
#include "unistd.h"

using namespace std;


void displayUsage(){
// Displays how to use this program
// TODO
cout << "Instruction: \n use -r to give rotation number \n use -f to give    file name" <<endl;
}

char caesar(char c, int r)
{
  if(isalpha(c))
  {
    if(islower(c))
    {
      c = (((c-97)+r)%26)+97; // 97 is a value of 'a'
    }
    else if(isupper(c))
    {
      c = (((c-65)+r)%26)+65; // 65 is a value of 'A'
    }
  }
  return c;
}


int main(int argc, char **argv){

  string text;
  char* input_file_name;
  int rotation;
  bool have_rotation = false;
  bool have_input_file_name = false;


    // process command-line arguement
    int opt = 0;
    extern char *optarg;
    static const char* opt_string = "r:f:";
    opt = getopt( argc, argv, opt_string);
    while(opt != -1) // While there are parameters to parse, do so
    {  
        switch(opt)
        {
            case 'r':
                have_rotation = true;
                rotation = atoi(optarg);
                break;
            case 'f':
                have_input_file_name = true;
                input_file_name = optarg;
                break;
            default:
                displayUsage();
                return 1;
        }
        opt = getopt( argc, argv, opt_string);  // Pull the next parameter, or 0 if none.
    }

    if(!have_rotation)
    {
      displayUsage();
      return 0;
    }

    if(have_rotation)
    {
      if(have_input_file_name)
      {     
        ifstream file(input_file_name);
        string text2, temp;
        while(!file.eof())
       {
          getline(file, temp);
          text2 += temp + "\n";
        }
        text = text2[text2.size()-2];
       }
      else
      {
      cout <<"Enter text:"<<endl;
      getline(cin, text);
      }
    }

      string output = "";
      for(int i = 0; i < text.size(); i++)
      {
        output += caesar(text[i],rotation);
      }
      cout<<output<<endl;


  return 0;
}

Upvotes: 0

Thomas Matthews
Thomas Matthews

Reputation: 57698

I guess the error is because you did not terminate your cipher array with a '\0'.

The printing function will process characters from an array (and possibly beyond) until it finds a '\0' character.

Your array should be one bigger to account for this terminating character.

Or get rid of the char array and use std::string.

Upvotes: 3

Related Questions