Why won't this compile?

Why doesn't this class compile?

import java.util.*;

public class Caesar
{
    public static void main(String [] args)
    {
        final boolean DEBUG = false;
        System.out.println("Welcome to the Caesar Cypher");
        System.out.println("----------------------------");
        Scanner keyboard = new Scanner (System.in);
        System.out.print("Enter a String : ");
        String plainText = keyboard.nextLine();
        System.out.print("Enter an offset: ");
        int offset = keyboard.nextInt();
        String cipherText = "";
        for(int i=0;i<plainText.length();i++)
        {
            int chVal = plainText.charAt(i);

            if (DEBUG) {int debugchVal = chVal;}

            chVal +=offset;

            if (DEBUG) {System.out.print(chVal + "\t");}

            while (chVal <32 || chVal > 127)
            {
                if (chVal < 32) chVal += 96;
                if (chVal > 127) chVal -= 96;

                if(DEBUG) {System.out.print(chVal+" ");}

            }

            if (DEBUG) {System.out.println();}

            char c = (char) chVal;
            cipherText = cipherText + c;

            if (DEBUG) {System.out.println(i + "\t" + debugchVal + "\t" + chVal + "\t" + c + "\t" + cipherText);}
        }
        System.out.println(cipherText);
    }
}

Answers


You define variable debugchVal inside an if block:

if (DEBUG) {int debugchVal = chVal;}

So it exists only inside that block. Later when you refer to it again:

if (DEBUG) {System.out.println(i + "\t" + debugchVal + "\t" + chVal + "\t" + c + "\t" + cipherText);}

it is not in scope anymore, so the compiler dutifully emits an error.

Modify the first code part like this:

int debugchVal;
if (DEBUG) {debugchVal = chVal;}

Declaration of variable debugchVal is inside the if block:

if (DEBUG) {int debugchVal = chVal;}

As a result it will not be available outside the if block. Move the declaration outside the if block as:

int debugchVal = /*some default value that makes sense if DEBUG is false */;
if (DEBUG) {debugchVal = chVal;}

Because you are defining debugchVal inside a scope and you try to use it later.

You are doing:

if (DEBUG) {int debugchVal = chVal;}

and later:

if (DEBUG) {System.out.println(i + "\t" + debugchVal + "\t" + chVal + "\t" + c + "\t" + cipherText);}

but since debugchVal is defined between braces it's a local definition just to that scope. Try to move it out of the scope:

int debugchVal = -1;
if (DEBUG) { debugchVal = chVal; }

You've declared debugchVal in a block like this:

if (DEBUG) {int debugchVal = chVal;}

That variable is only in scope for that block. It doesn't "exist" for the rest of the time.

You can do this:

int debugchVal = 0;
if (DEBUG) {
    debugchVal = chVal;
}

However, you might as well just always assign it (and give it a clearer name):

int initialChVal = chVal;

Having the assignment in the "non-debug" version won't hurt you.

You might also want to look at using something like java.util.Logging instead of this "DEBUG" pattern.


debugchVal is defined INSIDE the if block. So its scope is only that. Try to declare it outside (with a default value) and assign its correct value inside the if(DEBUG).

int debugChVal = 0;
if (DEBUG) {
   debugChVal = ...
}

Read the error message, find the line number, find the according line (plus the previous line), look at the error message itself ("cannot find symbol") and look for an undefined variable. In 99% of all cases it is a simple typo that should be obvious if you use an IDE with good syntax highlighting.


This is a scope resolution problem. The debugchval variable is not available in the scope of the last if. You need to declare it outside the if conditions


problem with scope on debugchVal:

import java.util.Scanner;

public class Caesar
{
   public static void main(String[] args)
   {
      final boolean DEBUG = false;
      System.out.println("Welcome to the Caesar Cypher");
      System.out.println("----------------------------");
      Scanner keyboard = new Scanner(System.in);
      System.out.print("Enter a String : ");
      String plainText = keyboard.nextLine();
      System.out.print("Enter an offset: ");
      int offset = keyboard.nextInt();
      String cipherText = "";
      for (int i = 0; i < plainText.length(); i++)
      {
         int chVal = plainText.charAt(i);
         int debugchVal = -1;

         if (DEBUG)
         {
            debugchVal = chVal;
         }

         chVal += offset;

         if (DEBUG)
         {
            System.out.print(chVal + "\t");
         }

         while (chVal < 32 || chVal > 127)
         {
            if (chVal < 32)
            {
               chVal += 96;
            }
            if (chVal > 127)
            {
               chVal -= 96;
            }

            if (DEBUG)
            {
               System.out.print(chVal + " ");
            }

         }

         if (DEBUG)
         {
            System.out.println();
         }

         char c = (char) chVal;
         cipherText = cipherText + c;

         if (DEBUG)
         {
            System.out.println(i + "\t" + debugchVal + "\t" + chVal + "\t" + c + "\t" + cipherText);
         }
      }
      System.out.println(cipherText);
   }
}

Need Your Help

Get UIViewController to reload different UIView programmatically

objective-c ios uiview uiviewcontroller

I am overriding the loadView method within a UIViewController as follows: