我正在尝试创建一个接受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.
答案 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);
}