为什么我会收到错误?

Why am I getting errors?

我正在尝试创建一个接受 cmd 行参数来加密明文的程序! 该程序在制作它时必须在其名称后接受一个 cmd 行参数,这将是明文(仅)字母字符由该键旋转的键(例如,它的数字被添加到真实字母表 ASCII 数字中,从而产生另一个字母表待打印!

它应该在出现一个参数时打印一条错误消息(例如这里:/make encipher) 而不是在这里:/make encipher 12 <-- 12 = key!

当 运行 程序没有 key 参数时,我遇到了分段错误,为什么?

这是完整代码。我发布它是因为我需要了解我的错误的确切位置在哪里 为什么会触发?!


#include <cs50.h>
#include <stdio.h>
#include <stdlib.h> //  To use atoi (converting a string to an int)
#include <ctype.h>
#include <string.h>

bool key_is_numb(string argv[]);
void encipher(string txt, int key);

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

    else
    {
    int key = atoi(argv[1]);
    string plaintext;

            if (argc == 2 && key > 0)
                {
                    plaintext = get_string("plaintext: ");
                    encipher(plaintext, key);  //  A function that prints the ciphered text
                    return 0;   //  returns Zero as main return value which means "All good"!
                }

            else if (argc == 1 || argc > 2 || key <= 0)
                {
                    printf("Usage: ./caesar key\n");
                    return 1;
                }

    }   //  End else.

}   // End main()å func.



bool key_is_numb(string argv[])
{
    int n = strlen(argv[1]);

    for (int i = 0; i < n; i++) //  checking element by element in the second string of the argv[] array of strings
    {
        if (isdigit(argv[1][i]) == 0)   //  if the entered string "key" contains chars other than digits.
        {
            return false;   //  break out of the if statement & the entire function key_is_numb()
                            //  and return false as soon as a letter is encountered.
        }

        else
        {
            continue;   //  go up & start the next iteration for the for loop.
        }
    //  if only digits encountered then this for loop will come to an end and exist from here.
    }   //  End for loop

    return true;   //  function exits and return boolean true from here.

}   // End key_is_numb() func.


void encipher(string txt, int key)
{
    printf("ciphertext: ");
    for (int i = 0, n = strlen(txt); i <= n; i++)    // strlen counts the number of elements in a string excluding '[=10=]'
    {
        char c = txt[i];

        if (isalpha(c))
        {
            if (isupper(c))
            {
                char m = 'A';   //  This is a modifyer character equals to 'A' = 65 so that it is indexed @ ZERO!
                printf("%c", (c - m + key) % 26 + m );
                //c = ((((int)txt[i] - 65) + key) % 26) + 65; //  char c = 65 <-- 65 is an ASCII code equals 'A'
            }
            else if (islower(c))
            {
                char m = 'a';   //  This is a modifying character 'a' = 97
                printf("%c", (c - m + key) % 26 + m );
            }
        }//  End if(alpha).

        else
        {
            printf("%c", c);
        }

    }   //  End for().
        printf("\n");

}   //  End encipher() func.

int n = strlen(argv[1]);

key_is_numb()

int key = atoi(argv[1]);

main().

如果您没有输入关键参数,argv[1] 等于 argv[argc] 是空指针,如 C17 §5.1.2.2.1/2 中所述。

任何访问其数据的尝试都是 undefined behavior 并且可能导致分段错误。

好吧,您假设 argv[1] 是在 key_is_numb 中定义的。但是,在 C 和 C++ 中,main 函数的第二个参数包含命令行参数。其中,在您的情况下,二进制文件的名称将作为第一个元素,然后是任何其他参数。这就是为什么当你 运行 程序没有参数时,它会出现段错误,因为没有参数可以放入 argv,也没有默认值。

在尝试读取 argv.

中的任何内容之前,您应该始终使用存储在 argc 中的数字检查 argv 的大小

你的段错误来自这一行 int n = strlen(argv[1]);,但我强烈建议你学习使用像 valgrind 这样的调试器软件,如果程序编译时带有调试标志,它会告诉你确切的行.

其他调试器也很有用,所以你应该学会使用它们,因为它们通常会报告这种错误。

您的代码假定始终存在 argv[1]。你应该检查 argc 它告诉参数的数量。例如:

int main(int argc, string argv[])
{
    if (argc < 2) {
        printf("Key required\n");
        exit (1);
    }