0

after running check50 I am getting an "output not valid ASCII text" error for the following problems:

:( encrypts "A" as "Z" using ZYXWVUTSRQPONMLKJIHGFEDCBA as key output not valid ASCII text

:( encrypts "a" as "z" using ZYXWVUTSRQPONMLKJIHGFEDCBA as key output not valid ASCII text

:( encrypts "ABC" as "NJQ" using NJQSUYBRXMOPFTHZVAWCGILKED as key output not valid ASCII text

:( encrypts "XyZ" as "KeD" using NJQSUYBRXMOPFTHZVAWCGILKED as key output not valid ASCII text

My guess is that it has something to do with cipher being a char array. I do not know how to change it to a string without causing the code to stop working.

#include <stdio.h> // Includes library for printf().
#include <cs50.h> // Includes library for string and get_string().
#include <string.h> // Includes library for strlen().

int main(int argc, string argv[]) // Program takes single command-line argument, where second word is cipher key
{

    if (argc != 2) // Checks that there are only two words in the command-line
    {
        printf("Usage: ./substitution key\n"); // Prints error message
        return 1;
    }

    int keylen = strlen(argv[1]); // Calculates number of characters in key
    int counter = 0; // Creates counter variable
    int diff[26]; // Creates 26-space array

    if (keylen != 26) // Checks that there are only 26 characters in the key
    {
        printf("Key must contain 26 characters.\n");
        return 1;
    }

    for (int m = 0; m < keylen; m++)
    {
        if ((argv[1][m] < 'A') || (argv[1][m] > 'Z' && argv[1][m] < 'a') || (argv[1][m] > 'z')) // Checks that each character in key is an alphabetical character
        {
            printf("Key must contain alphabetical characters only.\n");
            return 1;
        }
    }

    for (int k = 0; k < keylen; k++)
    {
        for (int l = 0; l < keylen; l++)
        {
                if ((argv[1][k] == argv[1][l]) || (argv[1][k] == argv[1][l] + 32) || (argv[1][k] == argv[1][l] - 32)) // Checks that each letter is used once and only once in key
                {
                    counter++;
                }
        }

    }

    if (counter != 26)
    {
        printf("Key must contain each character once.\n");
        return 1;
    }

    for (int i = 0; i < 26; i++)
    {
        if (argv[1][i] <= 'Z') // If key letter is uppercase...
        {
        diff[i] = argv[1][i] - (65 + i); // ...finds difference between key letter and 'A'
        }
        else // If key letter is lowercase...
        {
        diff[i] = argv[1][i] - (97 + i); // ...finds difference between key letter and 'a'
        }
    }

    string plain = get_string("plaintext: "); // Asks user for text to be ciphered

    char cipher[strlen(plain)]; // Creates a cipher array with equal length to plaintext

    for (int n = 0; n < strlen(plain); n++)
    {
        if (plain[n] < 'A' || plain[n] > 'z')
        {
            cipher[n] = plain[n]; // If plain letter isn't a letter, do not cipher
        }
        else if (plain[n] <= 'Z') // If plain letter is uppercase...
        {
            cipher[n] = (char) plain[n] + diff[plain[n] - 65]; // ...add the difference in the associated position of diff[] array
        }
        else if (plain[n] >= 'a')
        {
            cipher[n] = (char) plain[n] + diff[plain[n] - 97];
        }
        else
        {
            cipher[n] = plain[n]; // If plain letter still isn't a letter, do not cipher
        }
    }
    printf("ciphertext: %s\n", cipher); // Prints cipher
    return 0;
}


1 Answer 1

1

Your code reads from the outside of cipher which contains unknown values because your cipher is not terminated by \0.

Here is the link that you can debug memory errors or unexpected behavior in the future. The instruction for other C psets.

I copy & pasted the error message here.

 Memory access error: reading from the outside of a memory space; abort execution.
  # Reading 1 bytes from 0xffe4a6fd will read undefined values.
  #
  # The memory-space-to-be-read (start:0xffe4a6fc, size:1 bytes) is bound to 'cipher' at
  #    file:/prog.c::64, 10
  #
  #  0xffe4a6fc               0xffe4a6fc
  #  +------------------------------+
  #  | the memory-space-to-be-read  |......
  #  +------------------------------+
  #                                  ^~~~~~~~~~
  #        the read starts at 0xffe4a6fd that is right after the memory-space end.
  #
  # Stack trace (most recent call first) of the read.
  # [0]  file:/musl-1.1.10/src/string/memchr.c::25, 9
  # [1]  file:/musl-1.1.10/src/stdio/vfprintf.c::602, 8
  # [2]  file:/musl-1.1.10/src/stdio/vfprintf.c::678, 8
  # [3]  file:/musl-1.1.10/src/stdio/printf.c::13, 8
  # [4]  file:/prog.c::85, 5
  # [5]  [libc-start-main]
1
  • Thanks! That makes sense. I fixed the code by simply changing the encryption for loop condition from n < strlen(plain) to n <= strlen(plain). Runs perfectly now.
    – Dave Clark
    May 30, 2020 at 20:40

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .