I'm having some issues with this problem set from CS50. What I'm trying to do is encrypt a message and it doesn't print the result.
This is what debug50 shows ciphertext to be before it reaches printf
This is my code, it's a mess
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
bool check_key(char k);
string cipher (char text[], int key);
char alphabet[] = {'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'};
int main(int argc, string argv[])
{
// Check the key
// Check if it's more or less than 1 command line argument
// If not print ERROR
if (argc != 2)
{
printf("ERROR!\n");
return 1;
}
// Check if it's non negative - <= 0
// Check if it's a valid int
// If not print "Usage: ./caesar key"
char k = *argv[1];
if (check_key(k) == 0 || k == '0')
{
printf("Usage: ./caesar key\n");
return 1;
}
// Turn key into and int
int key = atoi(argv[1]);
// Get text
string plaintext = "ABC"; //I used this as a placeholder for get_string("plaintext: ");
string ciphertext = cipher(plaintext, key);
// Print cipher
printf("ciphertext: %s\n", ciphertext);
}
bool check_key(char k)
{
return isdigit(k); // Doesn't take negative values
}
string cipher (char text[], int key)
{
// Take plaintext characters and change each character of it with the character key positions away
// Add the character from alphabet array to another chiper array
// Add cipher array to cipher string and return
int position = 0;
int text_position = 0;
int text_length = 0;
char ciphertext[strlen(text)];
do
{
if (alphabet[position] == text[text_position])
{
int key_position = position key;
ciphertext[text_position] = alphabet[key_position];
position = 0;
text_position ;
}
else
{
position ;
}
}
while (text[text_position] != '\0');
string final_cipher = ciphertext;
return final_cipher;
}
I can't get it to print the ciphertext. I was wondering if the problem is because of the way I turned the array into a string, but I don't know any other way to do that besides using the overloaded operator.
CodePudding user response:
you need to allocate a place for ciphertext array with malloc and make your funktion return a char*, or if you have a String struct allocate for this a place and allocate for the char* also.
CodePudding user response:
In the function cipher
, in the line
char ciphertext[strlen(text)];
you are creating a local character array. The lifetime of this array will end as soon as the function cipher
ends.
In the line
string final_cipher = ciphertext;
you are not creating a copy of the array. Instead, you are creating a reference to the existing array. This is because the data type string
does not actually contain a string. It merely contains a reference to a character array, which may contain a null-terminated string. In week 4 of CS50, you will learn that the data type string
is actually an alias for char *
, which is a pointer, i.e. a reference to another variable or array.
Therefore, in the line
return final_cipher;
you are not returning a copy of the array, but you are merely returning a reference to the existing array ciphertext
.
However, as previously stated, the referenced array ciphertext
will cease to exist as soon as the function returns. Any attempt to use this reference afterwards will lead to undefined behavior.
Since the array ciphertext
no longer exists, the program will probably use the memory previously used by by the array for other purposes. That is probably why you are seeing the memory's value changing unexpectedly in the debugger. The function printf
is probably using that memory for something.
There are several solutions to this problem:
You could create a proper copy of the array
ciphertext
with a lifetime that does not end when the function ends, so that the functioncipher
can return the copy back tomain
. This would require you to use the functionstrcpy
and maybe alsomalloc
. However, you will probably not understand how to use any of these functions until you have completed week 4 of CS50, so I do not recommend this solution for now.Instead of attempting to store the individual characters of the ciphertext, you can print the individual characters immediately and then forget about them. This is probably the solution intended by the CS50 authors.