Caesar Cipher C#

I am having a problem with the step where I have to access the character at position i in the secretMessage array and store it in a variable.

This is my current code:

namespace CaesarCipher
{
  class Program
  {
    static void Main(string[] args)
    {
      // Make a secret message and store it in a variable; 
      char[] alphabet = new char[] {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z'};
      string secretMessage = "roman";
      char[] secretArray = secretMessage.ToCharArray();
      char[] encryptedMessage = new char[5];
      for (int i = 0; i < secretMessage.Length; i++) {
        char secret = encryptedMessage[5];
      }
    }
  }
}

This is my result:

Unhandled Exception: System.IndexOutOfRangeE
xception: Index was outside the bounds of th
e array.
   at CaesarCipher.Program.Main(String[] arg
s) in /home/ccuser/workspace/csharp-caesar-c
ipher/Program.cs:line 15

Hi @trk075

The line char[] encryptedMessage = new char[5]; initialises the variable encryptedMessage as a char array with a “size” of 5.

You’re later trying to access encryptedMessage[5]. Array indexing begins at 0, so the highest value index you can retrieve would be encryptedMessage[4].

:slight_smile:

Also,

Your code doesn’t currently do that…

2 Likes

I have a new problem I am trying to run the code to convert the message but it is not working.
This is my current code:
using System;

namespace CaesarCipher
{
class Program
{
static void Main(string args)
{
char alphabet = new char {‘a’, ‘b’, ‘c’, ‘d’, ‘e’, ‘f’, ‘g’, ‘h’, ‘i’, ‘j’, ‘k’, ‘l’, ‘m’, ‘n’, ‘o’, ‘p’, ‘q’, ‘r’, ‘s’, ‘t’, ‘u’, ‘v’, ‘w’, ‘x’, ‘y’, ‘z’};
string secretMessage = String.Join("", alphabet);
char secretArray = secretMessage.ToCharArray();
char encryptedMessage = new char[26];
for (int i = 0; i < secretMessage.Length; i++) {
char character = secretMessage[5];
char letter = alphabet[8];
encryptedMessage[1] = ‘f’;
}
int index = Array.IndexOf(alphabet, ‘a’ + 3);
Console.Write(secretMessage);
Console.ReadLine();
}
}
}

Hey @trk075

Couple of quick things.

Firstly, it helps a lot if you use the </> icon on the editor toolbar to retain the formatting of your code. It puts a block in your post, like so:
```
your code here
```
so that the formatting stays the same as in your editor, like this:

function someStuff(args) {
    keep white_space;
}

Secondly, I’ve reformatted the code to what I think you wrote and I get several errors.

Can you re-post your code using the code formatting button, and provide also the errors that you’re getting please? :slight_smile:

1 Like

This is my code in the way you wanted it:

namespace CaesarCipher
{
class Program
{
static void Main(string args)
{
char alphabet = new char {‘a’, ‘b’, ‘c’, ‘d’, ‘e’, ‘f’, ‘g’, ‘h’, ‘i’, ‘j’, ‘k’, ‘l’, ‘m’, ‘n’, ‘o’, ‘p’, ‘q’, ‘r’, ‘s’, ‘t’, ‘u’, ‘v’, ‘w’, ‘x’, ‘y’, ‘z’};
string secretMessage = String.Join("", alphabet);
char secretArray = secretMessage.ToCharArray();
char encryptedMessage = new char[26];
for (int i = 0; i < secretMessage.Length; i++) {
char character = secretMessage[5];
char letter = alphabet[8];
encryptedMessage[1] = ‘a’;
}
int index = Array.IndexOf(alphabet, ‘a’ + 3);
Console.Write(secretMessage);
Console.ReadLine();
}
}
}

And the error is that messages are not converting

Hi @trk075

Thanks for that.

If I run the code, I get the following errors:

main.cs(5,13): warning CS0028: ‘CaesarCipher.Program.Main(string)’ has the wrong signature to be an entry point
main.cs(7,26): error CS1922: A field or property ‘char’ cannot be initialized with a collection object initializer because type ‘char’ does not implement ‘System.Collections.IEnumerable’ interface
main.cs(8,24): error CS0103: The name ‘String’ does not exist in the current context
main.cs(9,34): error CS0029: Cannot implicitly convert type ‘char[]’ to ‘char’
main.cs(10,25): error CS0029: Cannot implicitly convert type ‘char[]’ to ‘char’
main.cs(13,23): error CS0021: Cannot apply indexing with [] to an expression of type ‘char’
main.cs(14,17): error CS0021: Cannot apply indexing with [] to an expression of type ‘char’
main.cs(16,13): error CS0103: The name ‘Array’ does not exist in the current context
main.cs(17,1): error CS0103: The name ‘Console’ does not exist in the current context
main.cs(18,1): error CS0103: The name ‘Console’ does not exist in the current context
error CS5001: Program ‘main.exe’ does not contain a static ‘Main’ method suitable for an entry point
Compilation failed: 10 error(s), 1 warnings
compiler exit status 1

Is that similar to what you’re getting?

You copied that from your post though, so it’s still different from the original >_<
It needs to be an exact copy otherwise… otherwise it’s different from the code you’re asking about, defeats the purpose of sharing it

At the very least the quotes are wrong, and there are missing using directives, and maybe there are more things after that, and it’s really hard to tell when one has stopped fixing formatting errors and when it actually looks like your code, if ever, not to mention that effort is spent on everything other than answering a question.

If your program doesn’t compile then you have to deal with the compile errors before you can consider how the program behaves. It sounds like you’re looking at error messages that are about a version you successfully compiled earlier.

2 Likes

Well my question is that the app is not running the messages that I want it to send as it is still the same. For example if I put abcdefghijklmnopqrstuvwxyz into secretMessage it comes out the same with no changes.

Ok. Can you post the code which you were able to compile, so we can see if we can help? :slight_smile:

(The code you posted previously doesn’t run, so you must be running some different code.)

using System;

namespace CaesarCipher
{
  class Program
  {
    static void Main(string[] args)
    {
      char[] alphabet = new char[] {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z'};
      string secretMessage = String.Join("", alphabet);
      char[] secretArray = secretMessage.ToCharArray();
      char[] encryptedMessage = new char[26];
      for (int i = 0; i < secretMessage.Length; i++)
      {
        char letter = secretMessage[9];
        int index = Array.IndexOf(alphabet, 'a');
        
      }
      Console.Write(secretMessage);
      Console.ReadLine();
    }
  }
}

It is on the Caesar Cipher project page.

I am using program.cs on the Caesar Cipher task on learn C#

That’s so much better. Now we can actually talk about the same code.

There’s no code that changes secretMessage, not sure why you’d expect the output to change? Like, there’s nothing in the code that you can point at and say “these actions are being applied to the input to change it”, is there?

If you look at every use of the variable you’re printing, the only time it gets changed is when it is first set.

There are also some compiler warnings (I highly recommend that you turn on all warnings if you haven’t already) which point out that some variables are created but never used. So if they were meant to do anything, they definitely aren’t.

$ mcs /warn:4 CaesarCipher.cs
CaesarCipher.cs(11,14): warning CS0219: The variable `secretArray' is assigned but its value is never used
CaesarCipher.cs(12,14): warning CS0219: The variable `encryptedMessage' is assigned but its value is never used
CaesarCipher.cs(16,13): warning CS0219: The variable `index' is assigned but its value is never used
Compilation succeeded - 3 warning(s)

If you remove them, along with some other things that also do nothing (empty loop for example), you end up with:

using System;

namespace CaesarCipher
{
  class Program
  {
    static void Main(string[] args)
    {
      string secretMessage = "giggles";
      Console.Write(secretMessage);
      Console.ReadLine();
    }
  }
}

(also, I think it’s very weird to read a line and ignore it at the end of a program. The program should probably terminate instead)

2 Likes

So, perhaps what you would do next is to think about what steps need to be carried out for the program to do its job, and then compare that with your current code to determine which of those steps are missing…and write the code for those steps? You’d probably want some kind of value where you build up the output, starting out empty or maybe zero’d out…And the loop would probably be filling that out, and then after the loop has finished you wouldn’t print the variable referring to the original string, but instead the one referring to the value you just built.

2 Likes

I’ve seen something similar in PowerShell to emulate the pause statement you can use with the Windows CLI, where using Read-Host "Hit ENTER to exit..." mimicks the Press any key to continue... prompt that pause would create.

This may be serving a similar purpose, to simply delay the program terminating?

Yeah it’s a windows thing. I’m not a windows user.
However, I still argue it isn’t how programs should behave, that the keep alive thing should be done by something separate.
For example I think visual studio might keep the console open for you, but if you double clicked your program from a graphical file explorer then you’d need it to pause. But if it’s a console program then it should be invoked from a console, sheesh.

Windows teaches its users to do all kinds of things wrong or not at all, people end up with really strange expectations about what things are and how they should behave. Is a program a window? If a program is not a window then why does it need to stay open, that doesn’t even make sense.

For better or worse, a significant proportion of people who use Windows aren’t technically minded. As an OS, it has a lower barrier to entry than Linux so it’ll get used. Same as with smartphones, or any technology - users want their tech to “just work”, with little regard to how or why.

Going back to the issue at hand, though, I had a crack at implementing a Caesar cipher in C# myself. Had to trawl the docs a lot, as I don’t know C#, but managed to get one working.

@trk075 - can you post the link to the exercise you’re doing? I’m not sure what the instructions, or requirements, of the exercise are that you’re attempting to meet. :slight_smile:

I don’t mean that windows is worse, only that it hides and distorts. Linux/most other unixes desktop is obviously garbage because it’s a second class citizen (nobody cares to make it good). Darwin is pretty but otherwise I don’t know much. It doesn’t have the same barrier to programming, you can for example create a hello world in C and compile it without downloading anything at all while the same process in windows…???

Hello. I just tried writing a method to decrypt the caesar cipher, but I get an “unhandled exception” I have no clue how to fix.
This is my code for the decrypt method:

static string Decrypt(char[] characterArray, int cipher)
    {
     char[] alphabet = new char[] {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z'};
      char[] encryptedMessage = new char[characterArray.Length];
      for (int i = 0; i < characterArray.Length; i++)
      {
        char letter = characterArray[i];
        if (Char.IsLetter(letter) == true)
        {
        int letterPos = Array.IndexOf(alphabet, letter);
        int newLetterPos = (letterPos - cipher) % alphabet.Length;
        char newLetter = alphabet[newLetterPos];  
        encryptedMessage[i] = newLetter;
        } 
      }
      return String.Join("", encryptedMessage);      
    }

when cipher = 3 and characterArray contains a,b or c I get an unhandled exception. This because 2© -3 gives -1 which is not a possible position in the array. I thought this was solved by doing int newLetterPos = (letterPos - cipher) % alphabet.Length. Because for example 2 -3 % 25 gives 24.
So why doesn’t it work? Why does the console tell me it is out of bounds of the array?

I hope you guys know what I mean and thanks in advance :slight_smile:

How big is the array and what index did you use? Easy enough to print out to find out.

■■■■ you are fast!
The array has a size of 25, because the alphabet contains 26 letters.
The index I use is characterArray[i]. Because I need to run the loop for each letter.

I also have an encrypt method. That method is exactly the same as this one except the ‘-’ in (letterPos - cipher) % alphabet.length is a ‘+’. That one works perfectly and doesn’t give any exceptions, even when I try to encrypt letters and the end of the array like x, y and z.