C 程序不处理非数字键

C program doesnt handle non numeric key

大家晚上好,希望大家一切顺利,我来找你们是因为我需要一些关于我编写的 C 代码的帮助,请记住,我刚刚开始用 C 编写代码,如果这个问题听起来很愚蠢,我很抱歉。

基本上我在做 CS50,我们正在编写一个加密消息的程序,所以我们首先要求用户提供一个命令行参数,这将是我们用来将纯文本转换为密文的密钥。所以基本上如果用户 运行s 的命令让我们说一个 2 即:./caesar 2 他稍后将输入的所有单词将是 "run" 两侧。

我的程序按预期工作,如果用户键入字母而不是数字,程序将不会提示用户输入消息。但是,如果用户 运行 是这样的命令行,例如 ./caesar 8x 程序将 运行 即使用户输入了一个字母,所以关于如何遍历用户命令参数的任何想法和如果有字母程序应该运行?谢谢!

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


int main(int argc, string argv[])
{

    if (argc == 2 && isdigit(*argv[1]))
    {

        int key = atoi(argv[1]);

        string plaintext = get_string("plaintext: ");
        printf("ciphertext: ");

        for (int i = 0, n = strlen(plaintext); i < n; i++)
        {
            if (isupper(plaintext[i]))
            {
                printf("%c", (((plaintext[i] + key) - 65) % 26) + 65);
            }

            else if (islower(plaintext[i]))
            {
                printf("%c", (((plaintext[i] + key) - 97) % 26) + 97);
            }

            else
            {
                printf("%c", plaintext[i]);
            }
        }

        printf("\n");
        return 0;
    }

    else if (argc == 1)
    {
        printf("NO KEY\n");
        return 1;
    }

    else if (argc >= 3 || argv[1] == (string) argv[1])
    {
        printf ("Usage: ./caesar key\n");
        return 1;
    }
}

编辑。已解决

这就是代码最终的样子,感谢@b运行o 的帮助 btw

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


int main(int argc, string argv[])
{

    if (argc == 2)
    {
        char *endp;
        long lkey;
        int errno = 0;

        lkey = strtol(argv[1], &endp, 10);
        if ((errno != 0) || (*argv[1] == 0) || (*endp != 0) || (lkey < 0) || (((int) lkey) != lkey) || argc >= 3)

            // this statement check to see the characters on argv[1] are all digits
        {
            printf("Usage: ./caesar key\n");
        }
        else // if the argv[1] is all digits then prompts the user for a plaintext
        {
            int key = atoi(argv[1]); // converts the key into an integer

            string plaintext = get_string("plaintext: ");
            printf("ciphertext: ");

            for (int i = 0, n = strlen(plaintext); i < n; i++)

                // goes thru each of the chars in plaintext and determines if is uppercase, lowercase or none.
            {
                if (isupper(plaintext[i]))
                {
                    printf("%c", (((plaintext[i] + key) - 65) % 26) + 65);

                    // it takes 65 and then sums it back to convert the character from the ASCII uppercase index and back
                }

                else if (islower(plaintext[i]))
                {
                    printf("%c", (((plaintext[i] + key) - 97) % 26) + 97);

                    // if the case is lower it takes 97 and then adds 97 back just to maintain the ASCII index.
                }

                else // if it not a lower case nor an uppercase, which means is a symbol then leave it like that.
                {
                    printf("%c", plaintext[i]);
                }
            }
            printf("\n");
            return 0;
        }
    }

    else if (argc == 1) // if the user doesnt prompt a key print no key to user
    {
        printf("NO KEY\n");
        return 1;
    }

    else if (argc >= 3) // if user prompts 3 or more keys into argv then prints error message regargind the usage
    {
        printf("Usage: ./caesar key\n");
        return 1;
    }

}

if the user runs the command line like this for example, ./caesar 8x the program will run eventhough the user typed a letter

您使用 atoi 从程序参数中获取数字,当达到非数字时它会停止,因此 8 和 8x 的结果相同。

如果参数从一开始就与数字不兼容,atoi 将默默地 return 0,这就是为什么 atoi 是危险的。无论如何,由于您之前的测试isdigit(*argv[1]),您不可能是那种情况。

any ideas on how to iterate thru the user command argument and if there is a letter the program should run

可能您想说 程序应该 运行.

要检查所有参数是否与数字兼容,您可以使用 strtol 进行转换:

if (argc == 2) {
  char * endp;
  long lkey;

  errno = 0;

  lkey = strtol(argv[1], &endp, 10);
  if ((errno != 0) || (*argv[1] == 0) || (*endp != 0) ||
      (lkey < 0) || (((int) lkey) != lkey)) {
    printf("invalid argument %s\n", argv[1]);
  }
  else {
    int key = (int) lkey;

    ...

因为您当前使用 int 作为 key 我检查该值是否与 int 兼容,我也检查它是否为正,因为这与您的使用兼容在您的版本中,您验证第一个字符是数字

晚上好, 我不知道我是否理解你的问题,但我会试一试。 问题是您正在检查 args 计数器是否为 2,并且第二个参数是否为数字。如果是这样,请执行您编写的以下代码。但如果不是呢? 您没有处理 argc==2 和 argv[1] 不是数字的情况。