为什么我会收到错误?
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);
}
我正在尝试创建一个接受 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);
}