Loading
Loading

Reputation: 19

C command line argument validation errors

Thank you everyone who helped me yesterday. I have one more issue with my code.

The purpose of the program is to take a command line argument and use it as a key to encrypt some plaintext entered by the user and to shift it by the number of letters given. The program should accept a single command-line argument, a non-negative integer. If any of the characters of the command-line argument is not a decimal digit, the program should print the message Usage: ./caesar key and return from main a value of 1.

When I test it, I receive the following error messages:

handles lack of key
    failed to execute program due to segmentation fault
:( handles non-numeric key
    timed out while waiting for program to exit
#include <cs50.h>
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include <math.h>
#include <stdlib.h>
        
//Declare the encrypting function
void encrypt(string plaintext, int k, string ciphertext);
        
int main(int argc, string argv[])
{
  string plaintext;
  int n = strlen(plaintext);
  char ciphertext[n+1]; //the lenght of the plaintext+ 1 extra char which i
  int k = atoi(argv[1]); //Convert string into an integer, i.e parsing
        
  if (argc != 2)
  {
    printf("Usage: ./caesar key\n");
    return 1;
  }
  else
  {
    for (int i = 0, m = strlen(argv[1]); i < m; i++)
    {
      if (isdigit(argv[1][i]))
      {
        plaintext = get_string("Plaintext:");
        encrypt(plaintext, k, ciphertext); //calling the encryption function
        printf("ciphertext: %s\n", ciphertext);
        return 0;
      }
      else
      {
        printf("Usage: ./caesar key\n");
        return 1;
      }
    }
  }
}

void encrypt(string plaintext, int k, string ciphertext)
{
  for (int i = 0, n = strlen(plaintext); i < n; i++)
  {
    if (isupper(plaintext[i]))
    {
      int  pi = plaintext[i] - 65;
      char ci = ((pi + k) % 26) + 65;
      ciphertext[i] = ci;
    }
    else if (islower(plaintext[i]))
    {
      int pi1 = plaintext[i] - 97;
      char ci1 = ((pi1 + k) % 26) + 97;
      ciphertext[i] = ci1;
    }
    else
    {
      ciphertext[i] = plaintext[i];
    }
  }
}

Upvotes: 0

Views: 202

Answers (1)

001
001

Reputation: 13533

I've updated your code as little as possible. Most of it was just re-arranging things.

int main(int argc, string argv [])
{
    // Check for correct number of args
    if (argc != 2)
    {
        puts("Please supply a key.");
        puts("Usage: ./caesar key");
        return 0;
    }

    // Check that argv[1] is all digits (i.e. positive integer)
    for (int i = 0, n = strlen(argv[1]); i < n; i++) {
        if (!isdigit(argv[1][i])) {
            puts("Usage: ./caesar key");
            return 1;
        }
    }

    // Get user string
    string plaintext = get_string("Plaintext:");
    if (!plaintext) return 1;
    // My compiler does not allow VLAs so I use malloc
    char *ciphertext = malloc(strlen(plaintext) + 1);
    int k = atoi(argv[1]); //Convert string into an integer, i.e parsing

    encrypt(plaintext, k, ciphertext); //calling the encryption function
    printf("ciphertext: %s\n", ciphertext);

    // Free up allocated mem
    free(ciphertext);
    free(plaintext);

    return 0;
}

void encrypt(string plaintext, int k, string ciphertext)
{
    int n = strlen(plaintext);
    for (int i = 0; i < n; i++)
    {
        if (isupper(plaintext[i]))
        {
            int  pi = plaintext[i] - 65;
            char ci = ((pi + k) % 26) + 65;
            ciphertext[i] = ci;
        }

        else if (islower(plaintext[i]))
        {
            int pi1 = plaintext[i] - 97;
            char ci1 = ((pi1 + k) % 26) + 97;
            ciphertext[i] = ci1;
        }
        else
        {
            ciphertext[i] = plaintext[i];
        }
    }
    // Don't forget to append nul-terminator
    ciphertext[n] = '\0';
}

Upvotes: 0

Related Questions