I am new to coding and have been doing it for a couple of weeks. I am now taking the cs50 course and Ive written the code for pset2 vigenere. When I used check50, I realized it wanted me to account for spaces and non-letters without skipping ahead in the key.
I added the "j--;" and, although the code is correct, it now creates extra random characters at the end of the ciphertext.
Also, when checking argv[1] for just letters in my code I have an if statement that has "int key = argv[1][i];" in the body. It doesn't do anything but I don't know how to have it just continue checking the next char without having an empty body, which is not allowed.
Any help would be appreciated! Thank you very much!
#include <cs50.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
int main(int argc, string argv[0])
{
//making sure it is not more than one command line
if (argc != 2)
{
printf("Usage: ./vigenere key \n");
return 1;
}
//if it is one command line, making sure the input is just letters
if (argc == 2)
{
for (int i = 0, n = strlen(argv[1]); i < n; i++)
{
if (isalpha(argv[1][i]))
{
int key = argv[1][i];
}
else
{
printf("Usage: ./vigenere key \n");
return 1;
}
}
}
//asking user for input text
string plaintext = get_string("plaintext: ");
printf("ciphertext:");
//going through a loop to turn plain text into ciphertext
int i = 0;
int n = strlen(plaintext);
string key = argv[1];
//looping through the key
while (i < n)
{
for (int j = 0, m= strlen(key); j < m; j++, i++)
{
//using the asci of each char as an int
int asc = (plaintext[i]);
int k = key[j];
//if lowercase
if (k >= 97 && k <= 122)
{
k -= 97;
}
else
{
k -= 65;
}
//if lowercase
if (asc >= 97 && asc <= 122)
{
printf("%c", ((((asc - 97) + k) % 26) + 97));
}
//if uppercase
else
{
if (asc >= 65 && asc <= 90)
{
printf("%c", ((((asc - 65) + k) % 26) + 65));
}
//if non-letter
else
{
printf("%c", asc);
j--;
}
}
}
}
printf("\n");
}
These are the expected vs actual results:
key: baz
plaintext: hello, world!
expected ciphertext: iekmo, vprke!
actual ciphertext: iekmo, vprke!!pu
Because program increments i
here for (int j = 0, m= strlen(key); j < m; j++, i++)
, it allows reading past the end of plaintext. The while loop is not going to evaluate i
until after the for loop is done. And this has potential for an infinite loop, depending on what the contents of memory are after the end of plaintext. If it never encounters something in the a-z or A-Z range, it will j--
forever.
You need to break out of the for loop if and when i == strlen(plaintext)
.