Segmentation fault with matrix assigned by strlen

0

I want to create the César cipher, also known as offset encryption, caesar.c with C. I receive the number in the variable as an argument ./caesar 2 for example. I use it in key . In an array of String s I receive the text without format. In encryptedASCII[strlen(s)] I will make the changes.

However, I receive a Segmentation fault . I thought it was because the size of the matrix was assigned dynamically but the error persisted when it did encryptedASCII[1000]

#include <cs50.h>
#include <stdio.h>
#include <ctype.h>
#include <stdlib.h>
#include <string.h>

int main(int argc, string argv[])
{
    int key = atoi(argv[2]);

    if (key<0)
    {
        return 1;
    }

    printf("¿Que quiere cifrar?\n");
    string s = GetString();
    int encryptedASCII[strlen(s)];
    char encryptedText[strlen(s)];

    for (int i = 0, n = strlen(s); i < n; i++)
    {
        if (isalpha(s[i]))
        {
        encryptedASCII[i] = ('s[i]' +key)%26;
        encryptedText[i]=encryptedASCII[i];
        }    
    }


    //Aqui estamos fijando el texto cifrado 
    for (int i = 0, n = strlen(s); i < n; i++)
    {
        printf("%c", encryptedText[i]);
    }

    return 0;

}
    
asked by ThePassenger 31.05.2016 в 15:40
source

1 answer

0

Your program has several problems:

encryptedASCII[i] = ('s[i]' +key)%26;

In this line, there are enough single quotes. In C, single quotes are used to declare characters. You are trying to access the character located in the position i of the buffer s then the correct thing would be to put:

encryptedASCII[i] = (s[i] +key)%26;

Another problem in this line is that %26 . If you make Z = X mod Y you will get in Z a number in the range (0..Y-1). If you take a look at the ASCII table you will see that the first characters correspond to non-printable symbols. Said in Christian: you are generating garbage. What you intend to put is:

encryptedASCII[i] = (((s[i] - 'A') + key)%26) + 'A';

That is, you first pass the character set, which will be in the range (A..Z), that is (65..90) to the range (0..26), then you make the displacement and calculate the module . After these steps you get a number in the range (0..26) and you only need to move the range again to obtain a character.

A third important error is in:

if (isalpha(s[i]))
{
  encryptedASCII[i] = (s[i] +key)%26;
  encryptedText[i]=encryptedASCII[i];
}

What's the point here encryptedASCII ? If you are a mere intermediary, you could use a variable type int to dry.

What happens if s[i] is not a letter? Basically that in encryptedText[i] you're going to leave the trash there because you have not initialized the buffer.

What happens if s[i] contains a lowercase character? That the result will be a random variable because the range (a..z) is not the same as (A..Z)

As a final note, comment that the type string that you use is a coarse alias of char* and the function GetString() is returning a pointer. Are you sure you do not have to erase that pointer to prevent memory leaks?

Why do you use GetString() instead of doing the reading by hand? There are two lines, you will not kill yourself to write:

char s[200];
scanf("%s",s);

I already notice that this library cs50.h is not at all standard and you will not learn anything using it.

And well, as a corollary, it would not hurt to make sure that argv[2] is valid.

When you pass arguments to a program by command line these are stored in argv . How many arguments are there? That's something that tells you argc .

And yes, the arguments will be found in:

  • argv[0] - > Executable name
  • argv[1] - > First parameter
  • argv[2] - > Second parameter
  • ...

Are you sure that argv[2] is not really argv[1] ?

Greetings.

    
answered by 31.05.2016 / 16:43
source