0

Code:

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

int main(int argc, string argv[])
{
    int key = 0;
    string plaintext;
    if (argc != 2) 
    {
        printf("Usage: ./caesar key \n");
    }
     else  
    {
        key = atoi(argv[1]);
        plaintext = get_string("Plaintext: ");
        printf("\n");
        printf("Ciphertext: ");
        
        for (int j = 0, n = strlen(plaintext); j < n; j++)
        {
            if (isupper(plaintext[j]))
            {
               printf("%c", (((plaintext[j] + key) - 65) % 26) + 65);
            }
            else if (islower(plaintext[j]))
            {
                printf("%c", (((plaintext[j] + key) - 97) % 26) + 97);
            }
            else 
            {
                printf("%c", plaintext[j]); 
            }
        }
        printf("\n");
    }
}
    

Run log:

~/pset2/caesar/ $ ./caesar 1
Plaintext: a

Ciphertext: b

I am working on pset2, caesar.

How can I check if my key is numerical or not?

I have tried many ways but failed, does someone know of a way I can do that? I am a beginner.

chux - Reinstate Monica
  • 143,097
  • 13
  • 135
  • 256
  • 2
    What do you mean by "weird space"? – Scott Hunter Dec 27 '20 at 21:01
  • *weird space between plaintext and ciphertext*. Do you mean this: `printf("\n");` before the `printf("Ciphertext: ");`? – kaylum Dec 27 '20 at 21:02
  • You see the empty line because you two newlines: the first is the one you typed after `a` to end the input, and the second is the `printf ("\n");` instruction after `get_string ()` – Roberto Caboni Dec 27 '20 at 21:08
  • Talking about the check of the integer "nature" of the input you have two options: 1) perform a check on the input string an discard those having undesired chars, 2) use `strtol ()` function (as described in [this answer](https://stackoverflow.com/a/14176593/11336762) ). – Roberto Caboni Dec 27 '20 at 21:15
  • 1
    So I need to use strtol() to check whether my key is numerical or not? If not, how can I do that? – Saara Luthra Dec 28 '20 at 03:36
  • A proper Caesar Cipher for `shift = 1` and input of `'a'`, results in an encoding of `'z'` not `'b'`. Avoid `atoi()` in your code. It provides no mechanism for error-detection and will happily accept `atoi ("my cow");` while silently returning `0` without any warning. At minimum `if ( sscanf (argv[1], "%d", &key) != 1) { /* handle error */ }` For full error handling, use `strtol()`. – David C. Rankin Dec 28 '20 at 04:11
  • OT: regarding: `for (int j = 0, n = strlen(plaintext); j < n; j++)` The function: `strlen()` returns a `size_t` (unsigned long) while `int` is a 'signed' value. I.E. this statement is comparing a signed value 'j' with a unsigned value 'n'. This will work for 'small' positive values but not otherwise. Your compiler should have told you about this problem. If your compiler did not tell you about this, then enable the warnings – user3629249 Dec 29 '20 at 02:34

1 Answers1

1

How can I check if my key is numerical or not?
I need to use strtol() to check whether my key is numerical or not?

Use strtol().

char *endptr;
errno = 0;  // Set to zero to later detect if `long` overflow 
            // or other implementation specific error occurred.
long key = strtol(argv[1], &endptr, 10);
//                                  ^^ base 10 number
//                         ^-----^     address to store end of conversion    

if (argv[1] == endptr) {
  puts("No conversion");
} else if (errno) {
  puts("Overflow");
} else if (*endptr != '\0') {
  puts("Junk after a number");
} else {
  printf("Success");
}

Maybe more tests to see if key in a sane range like 0 to 100 or whatever.

It is good that OP had a prior if (argc != 2) test to filter out (indirectly) argv[1] == NULL.

chux - Reinstate Monica
  • 143,097
  • 13
  • 135
  • 256