Caesar Shift Cypher:从标准输入读取文本并移动 n 个字符

Caesar Shift Cypher: read text from stdin and shift n characters

我正在尝试编写凯撒移位密码。引用西蒙·辛格的话:

The Caesar shift cipher replaces every letter with the letter that is a fixed number of places further down the alphabet. For example if the shift is 2, then A is replaced with C, B with D, C with E and so on. Or if there is a shift of 5 then A is replaced with F, B with G, C with H and so on.

我正在尝试从 stdin 读取文本并从传递给脚本 *argv[1] 的第一个参数读取移位的位数。为此,我将 *argv[1] 转换为 int 并减少 48(ASCII 为 0)。

#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>

int main(int argc, char **argv) {
        char buffer[100];
        char shifted_buffer[100];
        size_t nbytes;
        ssize_t bytes_read;
        int fd;
        fd = fileno(stdin);
        nbytes = sizeof(buffer);
        bytes_read = read(fd, buffer, nbytes);
        int i, n;
        n = *argv[1] - 48;
        for(i=1; i<bytes_read; i++) {
                shifted_buffer[i] = buffer[i]+n;
                }
        fprintf(stdout, "%s\n", shifted_buffer);
}

我期望的行为类似于:

echo -n 'abc' | ./Caesar 1
bcd

echo -n 'abc' | ./Caesar 2
cde

等等。 不幸的是,我得到的是:

echo -n 'abc' | ./Caesar 1
?cd??

为什么会这样?

我采纳了 Weather Vane 的所有建议:

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>

int main(int argc, char **argv) {
        char buffer[100];
        char shifted_buffer[100];
        size_t nbytes;
        ssize_t bytes_read;
        int fd;
        fd = fileno(stdin);                                             /* Get file descriptor of stdin */
        nbytes = sizeof(buffer);
        bytes_read = read(fd, buffer, nbytes);                          /* Read from stdin */
        int i, n;
        char *ptr;
        char *string = argv[1];                                                 /* Arguments to string */
        n = strtol(string, &ptr, 10);                                           /* Cast string to int */
        for (i=0; i<bytes_read; i++) {
                if      (buffer[i]<=90 && buffer[i]>=65) {                      /* If UPPERCASE CHARACTERS, then */
                        shifted_buffer[i] = ((buffer[i]-65+n)%26)+65;   /* shift n places and take the remainder of 26 */
                }
                else if (buffer[i]<=122 && buffer[i]>=97) {                     /* If LOWERCASE CHARACTERS, then  */
                        shifted_buffer[i] = ((buffer[i]-97+n)%26)+97;   /* shift n places and take the remainder of 26 */
                }
                else {                                                          /* if SPECIAL CHARACTERS, then  */
                        shifted_buffer[i] = buffer[i];                  /* just copy buffer */
                }
        }
        fprintf(stdout, "%s\n", shifted_buffer);                        /* Write shifted_buffer to stdout */
}

正在测试:

echo -n 'BZDRZQ’R VHED LTRS AD ZANUD RTROHBHNM' | ./Caesar 1
CAESAR’S WIFE MUST BE ABOVE SUSPICION

echo -n 'BZDRZQ’R VHED LTRS AD ZANUD RTROHBHNM' | ./Caesar 27
CAESAR’S WIFE MUST BE ABOVE SUSPICION

(以前不适用于 2 位数字)