-
problem with modulo
Code:
#include <stdio.h>
#include <cs50.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
int
main(int argc, char *argv[])
{
// check number of arguments
if (argc != 2)
{
printf("You must enter 1 argument. You also cannot enter more than 1.\n");
return 1;
}
// check if alpabetical
int keyLenght = strlen(argv[1]);
char *key = argv[1];
for (int i = 0; i < keyLenght; i++)
{
if ( !isalpha( key[i] ) )
{
printf("Argument must be alpabetical only. \n");
return 1;
}
}
// User enters message
printf("Enter your secret message: ");
char *inputTxt = GetString();
// encrypt and print cypher
printf("Secret message encrypted : ");
int inputLenght = strlen(inputTxt);
for (int i = 0; i < inputLenght; i++)
{
// transform key string into int from 1 to 26
int finalKey = key[i];
if ( isupper(finalKey) )
finalKey = finalKey - 65;
if ( islower(finalKey) )
finalKey = finalKey - 97;
finalKey = finalKey % keyLenght;
// encrypts capital letters
if (inputTxt[i] >= 65 && inputTxt[i] <= 90)
{
// transforms char from ascii to 1 to 26 and adds key
char cypherChar = inputTxt[i] - 65 + finalKey;
// modulo 1 to 26 number and transforms back to ascii
cypherChar = (cypherChar % 26) + 65;
// prints the character
printf("%c", cypherChar);
}
// encrypts small letters
else if (inputTxt[i] >= 97 && inputTxt[i] <= 122)
{
// transforms char from ascii to 1 to 26 and adds key
char cypherChar = inputTxt[i] - 97 + finalKey;
// modulo 1 to 26 number and transforms back to ascii
cypherChar = (cypherChar % 26) + 97;
// prints the character
printf("%c", cypherChar);
}
else
// prints the character
printf("%c", inputTxt[i]);
}
// end of program
printf("\n");
return 0;
}
There's a problem with the modulo on the finalKey variable. I never took math so I don't understand modulo very well but I think I need it to accomplish the desired result.
What the program is supposed to do:
Take the each letter of the key variable, transform it into its number from 0 to 25, then take the secret message and move each of the letters up in the alphabetical order by the number of one of the characters in key. When the key string runs out of character, it should go back to its first character.
What happens when I run my program:
jharvard@appliance (~/Desktop/cs50 projects): ./vigenere bbaa
Enter your secret message: aaaaaa
Secret message encrypted : bbaaad
Conclusion
I *think* everything is working except for this part:
Code:
// transform key string into int from 1 to 26
int finalKey = key[i];
if ( isupper(finalKey) )
finalKey = finalKey - 65;
if ( islower(finalKey) )
finalKey = finalKey - 97;
finalKey = finalKey % keyLenght;
If anyone can tell me what the problem is and maybe a simple way to understand modulo that would be awesome.
-
First thing I noticed is that you have spelled "length" and "alphabetical" wrong.
Does GetString use malloc? Can you show that function so that we can check it is correct?
Don't use magic numbers like 65 and 97, 90 or 122. Instead use things like 'a', 'A', or 'z'. Once you fix that up it will be easier to reason about whether it is correct or not, so I'll wait until you've done that before I look further.
Oh and make sure you say what the expected output is, as well as the actual output.
-
cypherChar % 26 is just the remainder when dividing cypherChar by 26.
-
An example:
Code:
#include <stdio.h>
int main(void) {
int i;
for(i=0;i<10;i++) {
printf("Number %d modulo 10 is: %d\n",i,i % 10);
printf("\nHit enter to continue");
getchar();
return 0;
}
Run the above snippet and see if it helps you better understand the modulo (remainder) operator.
-
I'd change Adak's example so the printf() line reads
Code:
fprintf("Number %d modulo 10 is: %d\n",i+16, (i+16) % 10);
The value 16 is arbitrary, but as long as it is a positive value, it will show the concept better. Possibly also increase the number of times around the loop from 10 to 29, to really make it clear. (Again, I picked the 29 at random).
-
Code:
// encrypt and print cypher
printf("Secret message encrypted : ");
int inputLenght = strlen(inputTxt);
for (int i = 0; i < inputLenght; i++)
{
// transform key string into int from 1 to 26
int finalKey = key[i];
if ( isupper(finalKey) )
finalKey = finalKey - 65;
if ( islower(finalKey) )
finalKey = finalKey - 97;
finalKey = finalKey % keyLenght;
I think you want to encrypt every letter of the message by adding a corresponding letter from the key like:
Code:
key: abc
message: Secret message
add key: abcabcabcabcab
result: Tgfsgw ohtudhg
Correct?
Then you have to use the modulo operator on the index variable (i) and not on "finalKey". "i" is the index for the message string and will probably be bigger than the length of your key string.
Bye, Andreas