I keep making changes to the looping part of this code and my check50 always fails. I don't know what's going on. Below is my code:
#include <stdio.h>
#include <ctype.h>
#include <cs50.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, string argv[])
{
// declare variables
int cipherText;
if (argc != 2)
{
printf("Usage: ./vigenere keyword");
printf("\n");
return 1;
}
// keyword is the second command line argument
string key = argv[1];
int keylen = strlen(argv[1]);
// iterate through keyword to check if alphabetical
for (int i = 0, n = strlen(argv[1]); i < n; i++)
{
if ((key[i] >= '0') && (key[i] <= '9'))
{
printf("Keyword must consist only of letters.");
return 1;
}
}
// get the plaintext
string plainText = GetString();
// encypher - iterate over the characters in string, print each one encrypted
for (int i = 0, j = 0, n = strlen(plainText); i < n; i++, j++)
{
// start the key again if key shorter than plainText
if (j >= strlen(key))
{
j = 0;
}
// skip key[j] if plainText[i] is not an alpha character
if (!isalpha(plainText[i]))
{
j = (j-1);
}
// makes Aa = 0, Zz = 25 for the uppercase letters
if (isupper(key[j]))
{
key[j] = (key[j] - 'A');
}
// makes Aa = 0, Zz = 25 for lowercase letters
else if (islower(key[j]))
{
key[j] = (key[j] - 'a');
}
if (isupper(plainText[i]))
{
cipherText = (plainText[i] - 'A');
cipherText = ((cipherText + key[j%keylen])%26) + 'A';
printf("%c", cipherText);
}
else if (islower(plainText[i]))
{
cipherText = (plainText[i] - 'a');
cipherText = ((cipherText + key[j%keylen])%26 + 'a');
printf("%c", cipherText);
}
else
{
printf("%c", plainText[i]);
}
}
printf("\n");
return 0;
}
Some answered this: "The first for loop has a problem. The condition is checking for i > keylen when it should be checking for i < keylen".
Also when computing the next output value, the steps should be
(p[i]-65) results in a number between 0 and 25
adding (key[i % keylen]) results in a number between 0 and 50
apply modulo 26 so the number is between 0 and 25 (this is the missing step)
then add 65 to get the output"
and it's what I tried to do.
Given this code:
int keylen = strlen(argv[1]);
// iterate through keyword to check if alphabetical
for (int i = 0, n = strlen(argv[1]); i < n; i++)
{
if ((key[i] >= '0') && (key[i] <= '9'))
{
printf("Keyword must consist only of letters.");
return 1;
}
}
Your test inside the loop identifies digits as 'not a letter' (which is valid), but ignores punctuation, spaces and so on. You should probably be using if (!isalpha(key[i])) for the test (and it is courteous to print the erroneous character in the error message, which should be printed on standard error, not standard output, and should end with a newline:
fprintf(stderr, "Keyword must consist only of letters (%c found at %d)\n",
key[i], i+1);
You could refine that so it doesn't try printing non-printable characters with %c, but this is a huge step in the right direction.
You really don't need to set n in the loop; you just set keylen before the loop, so you could have written:
for (int i = 0; i < keylen; i++)
However, that is mostly cosmetic. Your real problem lies here:
// start the key again if key shorter than plainText
if (j >= strlen(key))
{
j = 0;
}
// makes Aa = 0, Zz = 25 for the uppercase letters
if (isupper(key[j]))
{
key[j] = (key[j] - 'A');
}
// makes Aa = 0, Zz = 25 for lowercase letters
else if (islower(key[j]))
{
key[j] = (key[j] - 'a');
}
You modify the key string on each iteration through the key. Unfortunately, though, if any of the letters in the key is a or A, you've converted that to '\0', which means that strlen(key) returns a different answer from before. So, you should use keylen in place of strlen(). AFAICS, if there isn't an a or A, that part of the code is OK.
Later, you have:
if (isupper(plainText[i]))
{
cipherText = (plainText[i] - 'A');
cipherText = ((cipherText + key[j%keylen])%26) + 'A';
printf("%c", cipherText);
}
The j % keylen is superfluous; j is already limited to 0 .. keylen-1. Similarly with the code for lower-case text.
Putting these changes together, and dummying up a GetString() function using fgets(), I get:
#include <stdio.h>
#include <ctype.h>
// #include <cs50.h>
#include <stdlib.h>
#include <string.h>
typedef char *string;
static char *GetString(void)
{
static char buffer[4096];
if (fgets(buffer, sizeof(buffer), stdin) == 0)
{
fprintf(stderr, "EOF detected in GetString()\n");
exit(EXIT_SUCCESS);
}
buffer[strlen(buffer) - 1] = '\0';
return buffer;
}
int main(int argc, string argv[])
{
// declare variables
int cipherText;
if (argc != 2)
{
printf("Usage: ./vigenere keyword");
printf("\n");
return 1;
}
// keyword is the second command line argument
string key = argv[1];
int keylen = strlen(argv[1]);
// iterate through keyword to check if alphabetical
for (int i = 0; i < keylen; i++)
{
if (!isalpha(key[i]))
{
printf("Keyword must consist only of letters (%c at %d)\n",
key[i], i+1);
return 1;
}
}
// get the plaintext
string plainText = GetString();
// encypher - iterate over the characters in string, print each one encrypted
for (int i = 0, j = 0, n = strlen(plainText); i < n; i++, j++)
{
// start the key again if key shorter than plainText
if (j >= keylen)
{
j = 0;
}
// skip key[j] if plainText[i] is not an alpha character
if (!isalpha(plainText[i]))
{
j = (j - 1);
}
// makes Aa = 0, Zz = 25 for the uppercase letters
if (isupper(key[j]))
{
key[j] = (key[j] - 'A');
}
// makes Aa = 0, Zz = 25 for lowercase letters
else if (islower(key[j]))
{
key[j] = (key[j] - 'a');
}
if (isupper(plainText[i]))
{
cipherText = (plainText[i] - 'A');
cipherText = ((cipherText + key[j]) % 26) + 'A';
printf("%c", cipherText);
}
else if (islower(plainText[i]))
{
cipherText = (plainText[i] - 'a');
cipherText = ((cipherText + key[j]) % 26 + 'a');
printf("%c", cipherText);
}
else
{
printf("%c", plainText[i]);
}
}
printf("\n");
return 0;
}
Sample run:
$ ./vigenere bakedalaska
What a wonderful world! The news is good, and the Vigenere cipher is solved.
Xhkx d wznvorguv arrwd! Lre oegw ls rogn, aod dlh Vtgwxese mmshpr ac splfig.
$
Related
I'm facing the CS50's substitution problem.
It works, even though the code is not very optimized.
The problem is that i had to add this line of code at the end to make it work:
`
cipher_text[strlen(plain_text)] = '\0';
`
otherwise the lenght of the cipher_text is longer than expected.
Can you tell me why?
this is the code i've written.
`
#include <cs50.h>
#include <stdio.h>
#include <ctype.h>
#include <string.h>
int main(int argc, string argv[])
{
// check if there's 1 argument, if there are > 1 or < 0 print error message and return 1
if (argc != 2)
{
printf("Error, type 1 command\n");
return 1;
}
string key = argv[1];
long lenght = strlen(key);
// check if the key is valid (26 characters) or not, if not return 1 and print error
if (lenght != 26)
{
printf("Key must contain 26 characters.\n");
return 1;
}
// iterate throughout the key, element after element whith the 1st for loop
//check if contains letters or something else in the 1st if
//make the key all lower in order to compare letter repetition in the else if
//check for double letters (compare every letter (key[i]) with all the other letters) in the second for loop
for (int i = 0 ; i < lenght ; i++)
{
if (isalpha(key[i]) == 0) //(key[i] < 65 || key[i] > 90) && (key[i] < 97 || key[i] > 122))
{
printf("Key must contain only letters\n");
return 1;
}
else if (isupper(key[i]))
{
key[i] = tolower(key[i]);
}
for (int j = 0 ; j < lenght ; j++)
{
if (j != i && key[j] == key[i])
{
printf("You can't repeat letters in key (you've repeated the letter %c)\n", key[j]);
return 1;
}
}
}
//ask user for the text to cipher
string plain_text = get_string("plaintext: ");
char alphabet[] = "abcdefghijklmnopqrstuvwxyz";
char ALPHABET[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
char cipher_text[strlen(plain_text)];
// iterate through every index in plain_text
//if it is not alphabetical, add it to cipher text
//otherwise, check if it is lower or upper, and add to cipher_text
//
for (int j = 0; j < strlen(plain_text) ; j++)
{
if (isalpha(plain_text[j]) == 0)
{
cipher_text[j] = plain_text[j];
}
for (int x = 0 ; x < lenght ; x++)
{
if(islower(plain_text[j]))
{
if (plain_text[j] == alphabet[x])
{
cipher_text[j] = key[x];
}
}
else if (isupper(plain_text[j]))
{
if (plain_text[j] == ALPHABET[x])
{
cipher_text[j] = toupper(key[x]);
}
}
}
}
cipher_text[strlen(plain_text)] = '\0';
printf("ciphertext: %s\n", cipher_text);
return 0;
}
`
I tried to do the substitution problem in CS50's Week 2 Problem Set (essentially, we use an encryption key provided by the user to substitute values, preserving the original message case).
When I test the code myself, it prints all the characters correctly, but check50 says there is no output. See my test results in detail here.
:( encrypts "A" as "Z" using ZYXWVUTSRQPONMLKJIHGFEDCBA as key
expected "ciphertext: Z...", not ""
My code handles all the edge cases perfectly, but check50 says the substitution gives empty outputs ... but it works fine on my online terminal.
#include <cs50.h>
#include <stdio.h>
#include <ctype.h>
#include <string.h>
string substitution(string text, string key);
int main(int argc, string argv[])
{
// making sure there's exactly two arguments
if (argc != 2)
{
printf("Usage: ./substitution key\n");
return 1;
// making sure the key has 26 characters
} else if (strlen(argv[1]) != 26)
{
printf("Key must contain 26 characters.\n");
return 1;
}
// making sure there is no repeating characters in key
for (int i = 0; i < strlen(argv[1]); i++)
{
for (int j = 0; j < strlen(argv[1]); j++)
{
if (argv[i] == argv[j] && i != j)
{
printf("No repeating characters.\n");
return 1;
}
}
}
// if the key is valid...
printf("plaintext: ");
string text = get_string("Type a string: ");
string key = argv[1];
int l = strlen(text);
char ciphertext[l + 1];
// converts the whole key to uppercase
for (int k = 0; k < strlen(key); k++)
{
key[k] = toupper(key[k]);
}
string alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
// loops through all the characters in text
int length = strlen(text);
for (int i = 0; i < length; i++)
{
for (int j = 0; j < 26; j++)
{
if (isalpha(text[i]) && toupper(text[i]) == alphabet[j] && isupper(text[i]))
{
// printf("%c", key[j]);
ciphertext[i] = key[j];
break;
} else if (isalpha(text[i]) && toupper(text[i]) == alphabet[j] && islower(text[i]))
{
ciphertext[i] = tolower(key[j]);
// printf("%c", tolower(key[j]));
break;
} else
{
ciphertext[i] = text[i];
// printf("%c", text[i]);
}
}
}
// Add null char to make it a string
ciphertext[l] = '\0';
printf("ciphertext: %s\n", ciphertext);
return 0;
}
PS: My problem is similar to this question, but there was no solution provided. The code was excluded due to "academic honest policy", but I'm doing this merely because I'm genuinely stuck and I don't want to copy someone's solution.
Edit. 1: I included a piece of the code for brevity, but I was asked for the entire code. I'm working on the improvements you guys suggested.
by the way you can simply do this to encrypt you don't need all that extra stuff
for (int i = 0; i < strlen(plaintext); i++)
{
if (islower(plaintext[i]))
{
plaintext[i] = tolower(argv[plaintext[i] - 97]);
}
else if (isupper(plaintext[i]))
{
plaintext[i] = toupper(argv[plaintext[i] - 65]);
}
}
I am doing Caesar exercise from CS50 course, but it fail.
Here is the code:
# include <stdio.h>
# include <cs50.h>
# include <string.h>
# include <stdlib.h>
# include <ctype.h>
int main(int argc, string argv[])
{
if (argc == 2)
{
string key = argv[1];
int l = strlen(key);
for (int i = 0; i < l; i++)
{
// if key[i] is an alphabet character
if (isalpha(key[i]) != 0)
{
printf("Usage: ./caesar key\n");
return 1;
}
}
//change charater to number
int k = atoi(argv[1]);
//print Plaintext
string plaintext = get_string("Plaintext: ");
int n = strlen(plaintext);
char ciphertext[n];
//declare plaintext in ASCII
int nplaintext[n];
//Change plaintext to ASCII
for (int i = 0; i < n; i++)
{
nplaintext[i] = (int)plaintext[i];
}
//Declare ASCII for ciphertext which we name "plusplaintext"
int plusnplaintext[n];
for (int i = 0; i < n; i++)
{
//if Capital
if ((nplaintext[i] < 91) && (nplaintext[i] > 64))
{
plusnplaintext[i] = 65 + ((nplaintext[i] + k) - 65) % 26 ;
}
//if Lowercase
else if ((nplaintext[i] < 123) && (nplaintext[i] > 96))
{
plusnplaintext[i] = 97 + ((nplaintext[i] + k) - 97) % 26 ;
}
//if not character a -> z and A -> Z
else
{
plusnplaintext[i] = nplaintext[i];
}
}
for (int i = 0; i < n; i++)
{
ciphertext[i] = (char)plusnplaintext[i];
}
printf("ciphertext: %s\n", ciphertext);
}
else
{
printf("Usage: ./caesar key\n");
return 1;
}
}
Here is the output from Check50:
:) caesar.c exists.
:) caesar.c compiles.
**:( encrypts "a" as "b" using 1 as key, output not valid ASCII text**
:) encrypts "barfoo" as "yxocll" using 23 as key
:) encrypts "BARFOO" as "EDUIRR" using 3 as key
:) encrypts "BaRFoo" as "FeVJss" using 4 as key
:) encrypts "barfoo" as "onesbb" using 65 as key
**:( encrypts "world, say hello!" as "iadxp, emk tqxxa!" using 12 as key, output not valid ASCII text**
:) handles lack of argv[1]
When I test the code, sometimes it gives right result, sometimes it give the wrong result with some more characters at the end...
How can I correct my code?
The problem is with the logic here
//if Capital
plusnplaintext[i] = 65 + ((nplaintext[i] + k) - 65) % 26 ;
and
//if Lowercase
plusnplaintext[i] = 97 + ((nplaintext[i] + k) - 97) % 26 ;
use this logic instead
//if Capital
((((nplaintext[i] - 90) + 25) + key) % 26) + 65
//if Lowercase
((((nplaintext[i] - 122) + 25) + key) % 26) + 97
and it is also not necessary to assign the letters to a string, instead you can directly print it
#include <cs50.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <stdlib.h>
int main(int argc, string argv[])
{
// Error Checking on the command line argument
if (argc != 2)
{
printf("Usage: ./caesar key\n");
return 1;
}
else if (argc == 2)
{
for (int i = 0; i < strlen(argv[1]); i++)
{
if (isdigit(argv[1][i]) == 0)
{
printf("Usage: ./caesar key\n");
return 1;
}
}
}
int key = atoi(argv[1]);
string plain_text = get_string("plaintext: ");
printf("ciphertext: ");
for (int i = 0; i < strlen(plain_text); i++)
{
if (isalpha(plain_text[i]) != 0)
{
// printf("%c", plain_text[i] + key);
if (isupper(plain_text[i]))
{
printf("%c", ((((plain_text[i] - 90) + 25) + key) % 26) + 65);
}
else
{
printf("%c", ((((plain_text[i] - 122) + 25) + key) % 26) + 97);
}
}
else
{
printf("%c", plain_text[i]);
}
}
printf("\n");
}
Instead of using the ascii value of a letter in your code, it could be helpful to keep them as characters for the sake of clarity. I took a snippet of your code and changed the values to demonstrate.
//if Capital
if ((nplaintext[i] <= 'Z') && (nplaintext[i] >= 'A'))
{
plusnplaintext[i] = 'A' + ((nplaintext[i] + k) - 'A') % 26 ;
}
This makes it clear what those values represent, and you don't have to reference an ascii chart. More comments would also help a user, or yourself later on, understand what the purpose is for each part of your code.
You could also create some functions outside of your main function. For example, to check for all digits in command line input, or change the letters by the amount given in the key. If you start working on long programs of code, it could be helpful to have functions defined that you can use as many times as you need. It also cleans up your main for clarity.
This function below takes the character of each letter in the original text (char p), then "moves" the character by k spaces (int k, given by the user as the key in the command line). It works when called in a for loop in main that iterates over each letter in the original given string (text[i]), with i being increased for each time the loop executes.
char rotate(char p, int k)
{
// declare variable for the rotated letter to be stored
char c;
// check if it is a letter
if (isalpha(p))
{
// check for lowercase letter
if (islower(p))
{
// subtract ascii value from p to initialize to 0 - 25 for computations
p -= 'a'; // if p is a, it is now initialized to 0, if b to 1, if c to 3, etc
c = (p + k) % 26; // use Caesar's algorithm to rotate letters, 'wrapping' by using % 26
c += 'a'; // add ascii value back to result to get the rotated letter
}
// the only other option is uppercase since we checked for only letters, do the same for uppercase letters as for lowercase
else
{
p -= 'A';
c = (p + k) % 26;
c += 'A';
}
}
// if it is the nul character '\0' return 0, do not print
else if (p == '\0')
{
return 0;
}
// if not a letter or nul character, return the character as is
else
{
c = p;
}
// print the rotated letter which is now stored in c
printf("%c", c);
// return the value of c
return c;
}
Man I thought I had it! I've been working on the Vigenere problem and have gotten close but keep getting this error when I check. It looks like there's problem when the key has to loop back around. Thoughts?
Here is the error:
:) vigenere.c exists
:) vigenere.c compiles
:) encrypts "a" as "a" using "a" as keyword :( encrypts "world, say hello!" as "xoqmd, rby gflkp!" using "baz" as keyword \ expected output, but not "xoqmj, yfz gflkp!\n"
:( encrypts "BaRFoo" as "CaQGon" using "BaZ" as keyword \ expected output, but not "CaQAun\n"
:( encrypts "BARFOO" as "CAQGON" using "BAZ" as keyword \ expected output, but not "CAQAON\n"
:) handles lack of argv[1]
:) handles argc > 2
:) rejects "Hax0r2" as keyword
and here's my code:
#include <stdio.h>
#include <cs50.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
#define FALSE 0
#define TRUE 1
int main(int argc, string argv[])
{
string key = argv[1];
if (argc!= 2)
{
printf("please provide only one perameter \n");
// stop the program
return 1;
}
// iterate over the key to make sure its all alpha
int i,j;
for (i = 0, j = strlen(key); i < j; i++)
{
if (!isalpha(key[i]))
{
printf("please use only alphanumeric values \n");
return 1;
}
}
// now we have a key, "key" from the ONE perameter that is all alpha
string message = GetString();
int k = 0;
int keyindex;
for (i = 0, j = strlen(message); i < j; i++, k++)
{
if (isalpha(message[i]))
{
keyindex = k % strlen(argv[1]);
// covering the upper case letters
if (isupper(message[i]))
{
// covering the upper case letters with upper case key letters
if isupper(key[i])
{
// print cipher according to two upper case
int cipher = ((message[i] - 65 + key[keyindex] - 65) % 26)
+ 65;
printf("%c", cipher);
}
else
{
// print according to upper case message lower case key
int cipher = ((message[i] - 65 + key[keyindex] - 97) % 26)
+ 65;
printf("%c", cipher);
}
}
// this is for the non upper case letters
if (islower(message[i]))
{
if isupper(key[i])
{
// print cipher according to lower case message and
// upper case key letter
int cipher = ((message[i] - 97 + key[keyindex] - 65) % 26)
+ 97;
printf("%c", cipher);
}
else
{
// print according to lower case message and lower case key
int cipher = ((message[i] - 97 + key[keyindex] - 97) % 26)
+ 97;
printf("%c", cipher);
}
}
}
// non alpha symbols
else
{
printf("%c", message[i]);
}
}
// end program after iterating
printf("\n");
}
Problems with your program:
1) Sytax error that should keep it from compiling:
if isupper(key[i]) -> if (isupper(key[i]))
There are two of these so make sure to fix them both.
2) Incrementing k
int k = 0;
...
for (i = 0, j = strlen(message); i < j; i++, k++)
{
if (isalpha(message[i]))
{
keyindex = k % strlen(argv[1]);
There two was to approach this, either increment k on ever character or increment k on every letter. The designer of this problem chose letter so instead we need to do:
int k = 0;
...
for (i = 0, j = strlen(message); i < j; i++)
{
if (isalpha(message[i]))
{
keyindex = k++ % strlen(argv[1]);
3) Use keyindex now that we've defined it:
if isupper(key[i]) -> if isupper(key[keyindex])
There are two of these so make sure to fix them both.
Applying these changes and a little bit of style cleanup, we get:
#include <stdio.h>
#include <cs50.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
int main(int argc, string argv[])
{
if (argc != 2)
{
printf("please provide only one parameter \n");
return 1; // stop the program
}
string key = argv[1];
// iterate over the key to make sure it's all alpha
for (int i = 0, j = strlen(key); i < j; i++)
{
if (!isalpha(key[i]))
{
printf("please use only alphanumeric values \n");
return 1;
}
}
// now we have a key, "key" from the ONE parameter that is all alpha
string message = GetString();
for (int i = 0, k = 0, j = strlen(message); i < j; i++)
{
if (isalpha(message[i]))
{
int keyindex = k++ % strlen(key);
if (isupper(message[i])) // covering the upper case letters
{
if (isupper(key[keyindex]))
{
// print cipher according to both upper case
int cipher = ((message[i] - 'A' + key[keyindex] - 'A') % 26) + 'A';
printf("%c", cipher);
}
else
{
// print cipher according to upper case message and lower case key
int cipher = ((message[i] - 'A' + key[keyindex] - 'a') % 26) + 'A';
printf("%c", cipher);
}
}
else // this is for the non upper case letters
{
if (isupper(key[keyindex]))
{
// print cipher according to lower case message and upper case key letter
int cipher = ((message[i] - 'a' + key[keyindex] - 'A') % 26) + 'a';
printf("%c", cipher);
}
else
{
// print cipher according to both lower case
int cipher = ((message[i] - 'a' + key[keyindex] - 'a') % 26) + 'a';
printf("%c", cipher);
}
}
}
else // non alpha symbols
{
printf("%c", message[i]);
}
}
printf("\n"); // end program after iterating
}
Your code duplicates a lot of logic that you could combine with minor changes -- duplicated logic is one way that hard to find errors creep into code.
I am stuck in this example. Whenever I put the keyword 'bacon' I get the wrong answer.
Any idea why this is happening? I can't find the bug and I have tried a lot.
Can you please help me?
When I run this: ./vigenere bacon and input the text Meet me at the park at eleven am the answer should be Negh zf av huf pcfx bt gzrwep oz, but instead I get Negh ne og tjs qaty bt syfvgb bm
Update: I made some changes as suggested by the comments but still having the same problem.
#include<cs50.h>
#include<ctype.h>
#include<stdio.h>
#include<string.h>
int main(int argc, char *argv[])
{
//check if it has only two values
if (argc != 2)
{
printf("Usage: ./vigenere keyword\n");
return 1;
}
// check that every letter of keyword is alphabetic
char *keyword = argv[1];
int keylen = strlen(keyword);
for (int i = 0, n = keylen; i < n; i++)
{
if(!isalpha(keyword[i]))
{
printf("alphabetic keyword only!!!\n");
return 1;
}
if(isalpha(keyword[i]))
{
// if a letter of keyword is uppercase
if (isupper(keyword[i]))
{
keyword[i] = keyword[i] - 'A';
}
// if a letter of keyword is lowercase
if (islower(keyword[i]))
{
keyword[i] = keyword[i] - 'a';
}
}
}
char *text = GetString();
for (int i = 0, n = strlen(text); i < n; i++)
{
if (isalpha(text[i]))
{
// if plaintext letter uppercase then...
if (isupper(text[i]))
{
text[i] = ((text[i] - 'A') + (keyword[i % keylen])) % 26 + 'A';
printf("%c",text[i]);
// ^^^^^^ ----> repeat the pattern
}
// if plaintext letter lowercase then ...
if (islower(text[i]))
{
text[i] = ((text[i] - 'a') + (keyword[i % keylen])) % 26 + 'a';
printf("%c",text[i]);
}
}
// if no letters in plaintext then ...
if (!isalpha(text[i]))
{
text[i] = text[i];
printf("%c",text[i]);
}
}
printf("\n");
}
So as #BLUEPIXY suggested I had to use a different variable in order to get the right answer:
`char *text = GetString();
int k = 0;
for (int i = 0, n = strlen(text); i < n; i++)
{
if (isalpha(text[i]))
{
// if plaintext letter uppercase
if (isupper(text[i]))
{
text[i]= ((text[i] - 'A') + (keyword[k % keylen])) % 26 + 'A';
printf("%c",text[i]);
//^^^^^ ----> repeat the keyword pattern
}
// if plaintext letter lowercase
if (islower(text[i]))
{
text[i] = ((text[i] - 'a') + (keyword[k % keylen])) % 26 + 'a';
printf("%c",text[i]);
}
k++;
}`