-2

coding newbie here. I was practicing my C# to make a Caesar Cipher encoder. When I was making a method to encrypt my message, I got this error. (see it below).

Why am I getting this error?

I've tried to change the method return type to void. But then it says that it cannot convert void type to bool. Can I have some help here?

using System;

namespace CaesarCipher
{
  class Program
  {
    static void Main(string[] args)
    {
      Console.WriteLine(Encrypt("hello"));
    }

    static string Encrypt(string message)
    {
      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 = message.ToLower();
      char[] secretMessageChar = secretMessage.ToCharArray();

      char[] encryptedMessage = new char[secretMessageChar.Length];

      for (int i = 0; i < secretMessage.Length; i++)
      {
        if (!Char.IsLetter(secretMessageChar[i]))
        {
          continue;
        }

        char letter = secretMessageChar[i];
        int caesarLetterIndex = (Array.IndexOf(alphabet, letter) + 3) % 26;

        char encryptedCharacter = alphabet[caesarLetterIndex];

        encryptedMessage[i] = encryptedCharacter;

        return String.Join("", encryptedMessage);
      }
    }
  }
}

I expected the output to be something like 'khoor', but instead, it says this: Program.cs(12, 19): error CS0161: 'Prog)': not all code paths return a value

3 Answers3

1

Well, in case secretMessage ie empty your current implementation doesn't return anything and so you have compile time error. Move return String.Join("", encryptedMessage); out of the loop:

static string Encrypt(string message)
{
  // Let's not hardcode
  char[] alphabet = Enumerable
    .Range('a', 'z' - 'a' + 1)
    .Select(c => (char) c)
    .ToArray();

  string secretMessage = message.ToLower();
  char[] secretMessageChar = secretMessage.ToCharArray();

  char[] encryptedMessage = new char[secretMessageChar.Length];

  for (int i = 0; i < secretMessage.Length; i++)
  {
    if (!Char.IsLetter(secretMessageChar[i]))
    {
      continue;
    }

    char letter = secretMessageChar[i];
    int caesarLetterIndex = (Array.IndexOf(alphabet, letter) + 3) % 26;

    char encryptedCharacter = alphabet[caesarLetterIndex];

    encryptedMessage[i] = encryptedCharacter;

    // We don't return here...  
  }

  // But we return there: wether or not we've encrypted anything 
  // we return encryptedMessage

  // Shorter version of string.Join("", ...)
  return String.Concat(encryptedMessage);
}
Dmitry Bychenko
  • 180,369
  • 20
  • 160
  • 215
0

You need to return something outside the loop at the end of the method in case of secretMessage has length to 0, or the loop returns nothing.

First you need to check at the beginning for null or empty, so ToLower will not raise an exception.

Next you need to return something too at the end in case of the loop return nothing.

static string Encrypt(string message)
{
  if ( string.IsNullOrEmpty(message) )
    return message;
  ...
  return something or raise an exception.
}
  • Not exactly, `if (string.IsNullOrEmpty(message)) return message` is not enough: *counter example* `message = "123"` - it will not be encrypted, `Char.IsLetter` will return `false` which'll call `continue` in turn and thus `return String.Join("", encryptedMessage);` will never be reached – Dmitry Bychenko Nov 12 '19 at 13:27
0

Your for statement always return something on your first iteration if the if statement is not true. Outside the loop as @Oliver said you should return a string or null

Zinov
  • 3,817
  • 5
  • 36
  • 70