为什么会出现错误?

时间:2020-07-16 09:07:50

标签: c segmentation-fault cs50

我正在尝试创建一个接受cmd行参数以加密纯文本的程序! 程序在创建时必须在其名称后接受一个cmd行参数,这将是该键,该键由纯文本(仅)字母字符通过该键旋转(例如,其数字被添加到真实字母ASCII数字中,从而导致另一个字母要打印!

应该在存在一个参数时显示一条错误消息(例如,此处:/ make encipher) 代替这里:/ encipher 12 <-12 = 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 '\0'
    {
        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.

3 个答案:

答案 0 :(得分:3)

int n = strlen(argv[1]);

key_is_numb()

int key = atoi(argv[1]);

main()中。

如果您没有输入关键字参数,则{C {1}}中的argv[1]等于C17,第5.1.2.2.1 / 2节。

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

答案 1 :(得分:2)

假设您在rm -rf ./*.xcworkspace && rm -rf ./pods && pod install 中定义了argv [1]。但是,在C和C ++中,main函数的第二个参数包含命令行参数。在您的情况下,将以二进制名称作为第一个元素,然后是其他任何参数。这就是为什么在不带参数的情况下运行程序时会出现段错误的原因,因为没有参数要放入argv中,也没有默认值。

在尝试读取key_is_numb中的任何内容之前,应始终使用argv中存储的数字来检查argc的大小。

您的分段错误来自此行argv,但是我强烈建议您学习使用调试软件,例如valgrind,如果已使用debug标志编译了程序,它将告诉您确切的行。 / p>

其他调试器也确实非常有用,因此您应该学习使用它们,因为它们通常会报告此类错误。

答案 2 :(得分:2)

您的代码假定总有一个argv[1]。您应该检查argc,它可以告诉您参数的数量。例如:

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