The error happens after the user enters the plaintext. I'm quite new to this language and programming itself. Help would be greatly appreciated. Since I am working in the cs50 codespace I cant use the debugger for some reason and cant see the code dump as one other question suggested I can solve the issue myself. Been at this for a few days and had to post a question now. Thanks.
bool no_repeat(string key, int l);
string cipher(string key, string input, int l);
int main(int argc, string argv[])
{
if (argc == 2)
{
string key = argv[1];
int l = strlen(key);
int ver = 0;
for (int i = 0; i < l; i )
{
if (isalpha(key[i]))
{
ver ;
}
}
bool c = no_repeat(key, l);
if (strlen(argv[1]) == 0)
{
printf("Please enter an encryption key.\n");
return 1;
}
else if ((l != 26) || (ver != 26) || (c == false))
{
printf("Please input a correct encryption key.\n");
return 1;
}
}
else if (argc == 1)
{
printf("Please enter an encryption key.\n");
return 1;
}
string key = argv[1];
int l = strlen(key);
string input = get_string("plaintext:");
string cipherText = cipher(key, input, l);
printf("ciphertext: %s\n", cipherText);
return 0;
}
bool no_repeat(string key, int l)
{
for(int i = 0; i < l; i )
{
for (int k = i 1; k < l; k )
{
if (key[i] == key[k])
{
return false;
}
}
}
return true;
}
string cipher(string key, string input, int l)
{
string output = "";
string alphabets = "abcdefghijklmnopqrstuvwxyz";
for(int i = 0 ; i < l ; i )
{
int isUpper = isupper(key[i]);
key[i] = tolower(key[i]);
for (int k = i ; k < l ; k )
{
if (input[i] == alphabets[k])
{
output[i] = key[k];
}
else
{
output[i] = input[i];
}
}
if (isUpper != 0)
{
output[i] = toupper(output[i]);
}
}
return output;
}
CodePudding user response:
string
is probably a typedef char * string;
and in that case you cannot modify string output = "";
. Instead you want to use malloc()
to allocate a string sufficiently large, i.e.:
string output = malloc(strlen(input) 1);
if(!output) {
printf("malloc failed\n");
exit(1);
}
In cipher() you were also doing input[i]
but i
goes from 0
to strlen(key)
so you will likely result in out of bound access. For me, cipher() was returning the input for ciphertext. Here is the fixed version (note, removed the argument l
here and from caller as it's not needed):
string cipher(string key, string input) {
string output = malloc(strlen(input) 1);
if(!output) {
printf("malloc failed\n");
exit(1);
}
const string alphabet = "abcdefghijklmnopqrstuvwxyz";
size_t j = 0;
for(size_t i = 0; i < strlen(input); i , j ) {
string pos = strchr(alphabet, tolower(input[i]));
if(!pos) {
printf("letter %c not found in alphabet\n", input[i]);
exit(1);
}
output[j] = key[pos - alphabet];
}
output[j] = '\0';
return output;
}
and example execution:
~$ ./a.out abcdefghijklmnopqrtsuvwxzy # swap s and t
plaintext:test
ciphertext: sets
You don't have to store the alphabet, btw, as in ASCII pos - alphabet
is the same value as tolower(input[i]) - 'a'
.