我应该如何让用户输入我想要的信息?

100*_*oon 1 c caesar-cipher cs50

我刚开始学习计算机科学。

我正在通过在哈佛在线教授的 CS50 学习。好吧,我正在解决这个问题,我需要在命令行中从用户那里获取密钥,然后是明文,然后将该文本转换为 ASCII 中的密钥数量以生成密文。

这是我到目前为止所得到的。

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

int main(int argc, string argv[])
{
    if (argc != 2)
    {
        printf("Usage: ./caesar key\n");
    }

    {
        string plaintext = get_string("plaintext:  ");

        int key = atoi(argv[1]);
        int n = strlen(plaintext);
        char chr[n];

        printf("ciphertext: ");
        for (int i = 0; i < n; i++)
        {
            chr[i] = plaintext[i];
            if (isalpha(chr[i]))
            {
                if (isupper(chr[i]))
                {
                    chr[i] = (chr[i] - 65 + key) % 26 + 65;
                    printf("%c",chr[i]);    
                }
                else if (islower(chr[i]))
                {
                    chr[i] = (chr[i] - 97 + key) % 26 + 97;
                    printf("%c",chr[i]);    
                }            
            }
            else
            {
                printf("%c",chr[i]);        
            }
        }
    printf("\n");
    }
}
Run Code Online (Sandbox Code Playgroud)

好吧,我知道这看起来很松散,但这是我在全职工作的同时进行编程的第二周。

无论如何,我试图让用户通过使用 ./caesar “密钥的任意数字”来运行这个程序。

如果用户放入任何其他东西,那么我想打印“用法:./凯撒密钥\n”

到目前为止,我能想到的唯一方法是使用 argc != 2 制作 if 语句,这样我至少可以确保用户只在程序名称上输入一个命令。

但问题是,如果用户输入其他内容,例如 ./caesar HELLO ./caesar YolO

该程序仍在运行。

我想弄清楚我能做些什么来防止这种情况发生。

非常感谢您花时间阅读本文并提供帮助。

Ser*_*sta 5

这就是旧atoi函数被strtol. 前者只尝试从给定的字符串转换初始数字部分,而后者还告诉转换后的部分后剩余的内容。

因此,要确保用户将数字作为唯一参数,您可以执行以下操作:

int main(int argc, char *argv[]) {
    long key;
    int reject = 0;

    if (argc != 2) {                         // ensure one argument
        reject = 1;
    }
    else {
        char *end;
        key = strtol(argv[1], &end, 10);    // ensure not empty and numeric
        if ((*end != 0) || (end == argv[1])) reject = 1;
     }
    if (reject) {
        printf("Usage: %s key\n", argv[0]);
    return 1;
}
Run Code Online (Sandbox Code Playgroud)

sscanf也可以用。它甚至允许数字后面有空白字符,这不应该发生,因为argv数组是空白分隔的:

int main(int argc, char *argv[]) {
    int key;
    char empty[2];

    if ((argc != 2) || (sscanf(argv[1], "%d%1s", &key, empty) != 1)) {
        printf("Usage: %s key\n", argv[0]);
        return 1;
    }
    ...
Run Code Online (Sandbox Code Playgroud)