Home > OS >  Printf won't print string & debug shows that the string disappears after it reaches printf
Printf won't print string & debug shows that the string disappears after it reaches printf

Time:08-24

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

And this is after

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:

  1. You could create a proper copy of the array ciphertext with a lifetime that does not end when the function ends, so that the function cipher can return the copy back to main. This would require you to use the function strcpy and maybe also malloc. 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.

  2. 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.

  • Related