Okay, so I am completely stumped. I cannot understand why this programs output acts as if there is a random key everytime.
This program:
#include <cs50.h>
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include <stdlib.h>
int main(int argc, string argv[])
{
string sKey = argv[1];
// Make sure program was run with just one command-line argument
if (argc != 2 || atoi(argv[1]) < 0)
{
printf("Usage: ./caesar key\n");
return 1;
}
//Counts length of string and checks if all chars are digits
int counter = 0;
for (int i = 0; i < strlen(sKey); i )
{
if isdigit(sKey[i])
{
counter ;
}
}
//Checks if the key is a number
if (counter != strlen(sKey))
{
printf("Usage: ./caesar key\n");
return 1;
}
// Convert argv[1] from a `string` to an `int`
int key = (int)sKey;
// Prompt user for plaintext
string plaintext = get_string("Plaintext: ");
printf("Ciphertext: ");
for (int i = 0; i < strlen(plaintext); i )
{
if (isalpha(plaintext[i]) && isupper(plaintext[i]))
{
printf("%c", (((plaintext[i] - 'A') key) % 26) 'A');
}
else if (isalpha(plaintext[i]) && islower(plaintext[i]))
{
printf("%c", (((plaintext[i] - 'a') key) % 26) 'a');
}
else
{
printf("%c", plaintext[i]);
}
}
printf("\n");
}
Will output this:
caesar/ $ ./caesar 1
Plaintext: Hello, I'm Justin.
Ciphertext: Fcjjm, G'k Hsqrgl.
caesar/ $ ./caesar 1
Plaintext: Hello, I'm Justin.
Ciphertext: Pmttw, Q'u Rcabqv.
It seems to be due to the modulo operator, because when I isolated it I could recreate the issue. Is it one of my included libraries? I solved the problem on my own and ended up looking up a solution on youtube only to find my solution performed the same operations as the correct solution. I must be missing something.
Thank you
CodePudding user response:
This is because int key = (int)sKey;
does NOT convert the string to an integer... at least not in the way you think it does. It takes the string pointer sKey
(a memory address) to an integer. Since every time you run the progra this can be a different address, this is why it looks random. The correct way to convert a numerical string to a value is using atoi
or strtol
. The first part of your program should be something like this:
#include <cs50.h>
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include <stdlib.h>
int main(int argc, string argv[])
{
string sKey = argv[1];
int i;
// Make sure program was run with just one command-line argument
if (argc != 2)
{
printf("Usage: ./caesar key\n");
return 1;
}
// Checks if all chars are digits
for (int i = 0; sKey[i]; i )
if (!isdigit(sKey[i]) break;
// If the key contains any non-digits, error
if (sKey[i])
{
printf("Usage: ./caesar key\n");
return 1;
}
// Convert argv[1] from a `string` to an `int`
int key = atoi(sKey);
// The rest should be fine