title: PSET 2: Vigenere Cipher partially working?
body: <p>I have created the following code as an answer to CS50x PSET2: Vigenere and it works to some extent however when running through check50 I get some errors listed below:</p>
  
  <pre><code>:) vigenere.c exists.
  :) vigenere.c compiles.
  :) encrypts "a" as "a" using "a" as keyword
  :( encrypts "barfoo" as "caqgon" using "baz" as keyword - output not valid ASCII text 
  :( encrypts "BaRFoo" as "CaQGon" using "BaZ" as keyword - output not valid ASCII text 
  :) encrypts "BARFOO" as "CAQGON" using "BAZ" as keyword
  :( encrypts "world!$?" as "xoqmd!$?" using "baz" as keyword- output not valid ASCII text 
  :( encrypts "hello, world!" as "iekmo, vprke!" using "baz" as keyword- output not valid ASCII text 
  :) handles lack of argv[1]
  :) handles argc &gt; 2
  :( rejects "Hax0r2" as keyword - timed out while waiting for program to exit 
  </code></pre>
  
  <p>What seems to be happening is where the key contains a high value (i.e z/Z) it causes the code to skip to the next line and miss out what appears to be random sequences. eg. in the first word of the string it missed out the 3rd character, then the second word it misses the 3rd and 4th and then the third word the 1st. I just can't understand what is happening.  </p>
  
  <p>I have used printf to ensure that all the variables being set and passed into functions are correct at runtime. The functions themselves are returning the correct responses (except validation of Hax0r2). I have tried debugging by comparing results to an online vigenere cipher tool.  </p>
  
  <pre><code>#include &lt;cs50.h&gt;
  #include &lt;stdio.h&gt;
  #include &lt;string.h&gt;
  #include &lt;ctype.h&gt;
  #include &lt;stdlib.h&gt;
  
  int Validate1(int argc);
  int Validate2(string argv);
  void Cypher(string x);
  void KeyCalc(string argv);
  
  string MESSAGE;
  int LENGTH;
  int *KEY;
  int COUNTER = 0;
  
  int main(int argc, string argv[])
  {
      //Check if right amount of arguments are supplied
      int Val1 = Validate1(argc);
  
      if (Val1 == 0)
      {
          //Check if argument is a string of chars
          int Val2 = Validate2(argv[1]);
  
          if (Val2 == 0)
          {
              //get the string length
              LENGTH = strlen(argv[1]);
  
              //Dynamically update KEY array length
              KEY = (int *)malloc(LENGTH * sizeof(*KEY));
              if (KEY == NULL)
              {
                  fprintf(stderr, "malloc failed\n");   
              }
  
              //calculate the key
              KeyCalc(argv[1]);
  
              //get the message from the user to be encrypted
              MESSAGE = get_string("plaintext: ");
              printf("ciphertext: ");
  
              //encrypt message from user
              Cypher(argv[1]);
              free(KEY);
              return 0;
          }
          else
          {
              //validation failed
              printf("Usage: ./vigenere keyword\n");
              return 1;
          }
      }
      else
      {
          //validation failed
          printf("Usage: ./vigenere keyword\n");
          return 1;
      }
  }
  
  //Validate the number of arguments supplied
  int Validate1(int argc)
  {
      if (argc != 2)
      {
          return 1;
      }
      else
      {
          return 0;   
      }
  }
  
  //Validate the argument is a string
  int Validate2(string argv)
  {
      int k = 0;
  
      //loop through all characters in argument line string and check if alphabetic 
      for (int i = 0; i &lt; LENGTH; i++)
      { 
          if isalpha(argv[i])
          {
              //Do Nothing
          }
          else
          {
              k++; 
          }
      }
  
      //k counts the number of non-alphabetic characters, so if &gt; 0 then invalid input
      if (k &gt; 0)
      {
          return 1;
      }
      else
      {
          return 0;    
      }
  }
  
  
  void Cypher(string x)
  {
      //identify the length of the message to be coded
      int Mlength = strlen(MESSAGE);
  
      //identify the length of the key
      int Slen = strlen(x);
  
      //cycle through all characters in message supplied by user
      for (int i = 0; i &lt; Mlength; i++)
      {
          // loop through key
          if (COUNTER &gt; Slen - 1)
          {
              COUNTER = 0;
          }
          //check if the character is alphabetic
          if (isalpha(MESSAGE[i]))
          {
              //convert the character to ASCII int value
              char l = MESSAGE[i];
  
              //add key value to message value and wrap around ascii mapping
              if (isupper(MESSAGE[i]))
              {
                  l = l + KEY[COUNTER];
                  if (l &gt; 'Z')
                  {
                      l = l - 26;    
                  }
              }
              else
              {
                  l = l + KEY[COUNTER];
                  if (l &gt; 'z')
                  {
                      l = l - 26;    
                  }    
              }
  
              //convert value back into character and store in array
              MESSAGE[i] = (char) l;
              // print character 
              printf("%c", MESSAGE[i]);
              COUNTER++;
          }
          else
          {
              //character is 'numeric' or 'symbol' or 'space' just display it
              printf("%c", MESSAGE[i]);
          }
      }
      printf("\n");
  }
  
  void KeyCalc(string argv)
  {
      //convert key entry to values A/a = 0 to Z/z = 26
      for (int i = 0; i &lt; LENGTH; i++)
      {
          char k = argv[i];
          if (islower(argv[i]))
          {
              KEY[i] = k - 'a'; 
          }
          else
          {
              KEY[i] = k - 'A'; 
          }      
      }    
  }
  </code></pre>
  
  <ul>
  <li>encrypts "barfoo" as "caqgon" using "baz" as keyword</li>
  <li>encrypts "BaRFoo" as "CaQGon" using "BaZ" as keyword </li>
  <li>encrypts "world!$?" as "xoqmd!$?" using "baz" as keyword</li>
  <li>encrypts "hello, world!" as "iekmo, vprke!" using "baz" as keyword</li>
  <li>rejects "Hax0r2" as keyword</li>
  </ul>