C编程中的Segmentation fault错误
Segmentation fault error in C programming
当我只是 运行 ./caesar 命令时,我在这个程序中遇到 分段错误 。我发现当我在代码开头写 int length=strlen(argv[1]); 时会打印错误,当我将此行放在 ( for 循环),但我不明白为什么它在那里工作正常,而不是在程序的顶部??
非常感谢您的帮助!!提前致谢。
int main(int argc,string argv[])
{
int s=0;
int length=strlen(argv[1]); ##GETS ERROR
if ( argc !=2)
{
printf("Usage:./caesar key\n");
return 1;
}
else
{
int length=strlen(argv[1]); ##WORKS FINE
for (int i = 0; i < length ; i += 1)
{
int c= argv[1][i];
if (isdigit(c))
{
s += 1;
}
else
{
s+=0;
}
}
printf("%i\n",s);
if (length==s)
{
int key = atoi(argv[1]);
printf("int:%i\n",key);
}
else
{
printf("Usage:./caesar key\n");
}
}
}
您的第一次尝试:
int length=strlen(argv[1]); ##GETS ERROR
这会报错,因为,有一个参数,当你调用main时:没有索引为1的参数。这种方式是不安全的,所以你应该先处理参数的数量,然后,parse/read/use 参数。
第二次尝试时(处理 argc 的地方):
if (argc !=2)
{
printf("Usage:./caesar key\n");
return 1;
}
else
{
int length=strlen(argv[1]); ##WORKS FINE
.....
}
你已经确定了,你有两个参数。因为,如果没有,您的代码就会退出。问题是,您不使用相同的测试用例测试您的代码版本:您的新代码和新代码(有 if 和没有)将使用两个参数;但是,如果只有一个参数,旧的将失败,而第二个则不会(它将只是程序中的 return)。
很可能,您需要在争论中使用 caesar。不要只输入“./caesar”,而是输入 "caesar blah"。更重要的是,您应该编写一些代码来检查参数的数量。例如,您可以写类似
#include <stdlib.h>
#include <stdio.h>
int main(int argc, char *argv[]) {
if (argc < 2) {
fprintf(stderr, "Usage: %s arg1 arg2 ...\n", argv[0]);
return EXIT_FAILURE;
}
/*
...
Fill in code
...
*/
}
编辑:我觉得这里发生了一些误解。如果将 "int s = strlen(argv[1]);" 放在片段 "if (argc != 2) ..." 之前,则 caesar 程序将尝试对不存在的字符串调用 strlen,从而导致段错误。本质上,在做任何其他事情之前总是先写错误检查代码("if (argc != 2) ...")。此外,在 "if (argc != 2) ..." 之后不需要 else。我觉得去掉 else 关键字并将正文保留在 else 子句中是更好的风格。
当我只是 运行 ./caesar 命令时,我在这个程序中遇到 分段错误 。我发现当我在代码开头写 int length=strlen(argv[1]); 时会打印错误,当我将此行放在 ( for 循环),但我不明白为什么它在那里工作正常,而不是在程序的顶部??
非常感谢您的帮助!!提前致谢。
int main(int argc,string argv[])
{
int s=0;
int length=strlen(argv[1]); ##GETS ERROR
if ( argc !=2)
{
printf("Usage:./caesar key\n");
return 1;
}
else
{
int length=strlen(argv[1]); ##WORKS FINE
for (int i = 0; i < length ; i += 1)
{
int c= argv[1][i];
if (isdigit(c))
{
s += 1;
}
else
{
s+=0;
}
}
printf("%i\n",s);
if (length==s)
{
int key = atoi(argv[1]);
printf("int:%i\n",key);
}
else
{
printf("Usage:./caesar key\n");
}
}
}
您的第一次尝试:
int length=strlen(argv[1]); ##GETS ERROR
这会报错,因为,有一个参数,当你调用main时:没有索引为1的参数。这种方式是不安全的,所以你应该先处理参数的数量,然后,parse/read/use 参数。
第二次尝试时(处理 argc 的地方):
if (argc !=2)
{
printf("Usage:./caesar key\n");
return 1;
}
else
{
int length=strlen(argv[1]); ##WORKS FINE
.....
}
你已经确定了,你有两个参数。因为,如果没有,您的代码就会退出。问题是,您不使用相同的测试用例测试您的代码版本:您的新代码和新代码(有 if 和没有)将使用两个参数;但是,如果只有一个参数,旧的将失败,而第二个则不会(它将只是程序中的 return)。
很可能,您需要在争论中使用 caesar。不要只输入“./caesar”,而是输入 "caesar blah"。更重要的是,您应该编写一些代码来检查参数的数量。例如,您可以写类似
#include <stdlib.h>
#include <stdio.h>
int main(int argc, char *argv[]) {
if (argc < 2) {
fprintf(stderr, "Usage: %s arg1 arg2 ...\n", argv[0]);
return EXIT_FAILURE;
}
/*
...
Fill in code
...
*/
}
编辑:我觉得这里发生了一些误解。如果将 "int s = strlen(argv[1]);" 放在片段 "if (argc != 2) ..." 之前,则 caesar 程序将尝试对不存在的字符串调用 strlen,从而导致段错误。本质上,在做任何其他事情之前总是先写错误检查代码("if (argc != 2) ...")。此外,在 "if (argc != 2) ..." 之后不需要 else。我觉得去掉 else 关键字并将正文保留在 else 子句中是更好的风格。