ccommand-linesegmentation-faultcs50argv

"Segmentation fault(core dumped)" (problem with argv)


So I tried debugging it and I know it's related to the argv but I'm not sure what is happening.

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

string replace();

int main(int argc, string argv[])
{
  if (strlen(argv[2]) != 26)
  {
    printf("The cipher must be 26 characters\n");
    return 0;
  }

To be clear, debug says the problem occurs on the line that says

if (strlen(argv[2]) !=26

The problem given is "segmentation fault(core dumped). This only happens when I enter text after executing the program.

So the later text is here:

  string plaintext = get_string("Plaintext: ");
  string word = plaintext;
  string result = replace(word);
}

string replace(string word, int argc, string argv[])
{
  string coded = NULL;
  for(int i = 0; i < strlen(word); i++)
  {
    int c = tolower(word[i]);
    int n = c - 97;
    if (n < 0 || n > 26)
    {
      n = c;
    }
    coded[i] = argv[2][n];
  }
  printf("coded: %s", coded);
  return 0;
}

I basically want to turn whatever the plaintext string is into a code using a cipher that was inputted in the command line argument. I know that I have some errors (like punctuation will not convert) because I'm new to this, but I feel confident I can figure those out on my own. I just want to figure out why it's giving me this specific error.


Solution

  • In the comments section, you stated that you are calling your program like this:

    ./substitution YTNSHKVEFXRBAUQZCLWDMIPGJO
    

    This means that

    Therefore, the line

    if (strlen(argv[2]) != 26)
    

    is not referring to a valid string and may cause a segmentation fault when you use strlen on that invalid reference. This appears to be exactly what is happening here.

    For this reason, you should use argv[1] instead of argv[2].

    Generally, it is a good idea to always check the value of argc ("argument count") before accessing the array argv ("argument vector"). Otherwise, if the user dies not pass any command-line arguments (other than the program name) and you try to read argv[1], you will be using an invalid reference and you may be causing a segmentation fault.

    Therefore, I recommend that you change the lines

    int main(int argc, string argv[])
    {
      if (strlen(argv[2]) != 26)
      {
        printf("The cipher must be 26 characters\n");
        return 0;
      }
    

    to the following:

    int main(int argc, string argv[])
    {
        if ( argc < 2 )
        {
            printf( "You must specify at least one argument!\n" );
            exit( EXIT_FAILURE );
        }
    
        if ( strlen(argv[1]) != 26 )
        {
            printf( "The cipher must be 26 characters\n" );
            exit( EXIT_FAILURE );
        }
    

    Note that you must #include <stdlib.h> to use the function exit. Using exit instead of return has the advantage that it can be used to immediately terminate your program also outside the function main. In contrast to exit, the return statement can only do this when used inside the function main, so it is generally better to use exit for consistency, even if using return is sufficient in this case. Otherwise, if you for some reason decide to move the code into another function, it will stop working.

    Another issue, which can also lead to a segmentation fault, is that in the function replace, you appear to be not replacing the characters in the original string, but rather attempting to create a new string to which to write the converted characters. However, in week 2 of CS50, you have not yet learnt how to allocate memory for a string whose size is unknown at compile-time, and how to copy such a string. Also, you have not yet learnt how to return a string from a function. You will only learn this in week 4 of CS50, in which you also learn what pointers are. Therefore, I do not recommend that you attempt to create a copy of the string, as this is also not required by the assignment. Instead, I recommend that you simply overwrite the characters of the existing string, as that is how the assignment is intended to be solved.