lower/upper 转换中的分段错误
segmentation fault in lower/upper conversion
这是我的全部源代码:
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
int main(int argc, char *argv[])
{
printf("usage: %s l(ower)/u(pper)", argv[0]);
int (*convert)(int c) = NULL;
int c;
if (argc != 2)
printf("usage: %s l(ower)/u(pper)", argv[0]);
if (strcmp(argv[1], "l") == 0 || strcmp(argv[1], "lower") == 0)
convert = tolower;
else if(strcmp(argv[1], "u") == 0 || strcmp(argv[1], "upper") == 0)
convert = toupper;
else
printf("usage: %s l(ower)/u(pper)", argv[0]);
while ((c = getchar()) != EOF)
putchar((*convert)(c));
return 0;
}
我用 cc 编译这段代码,运行 在 MacBook 上编译。
收到分段错误。
你的代码有几个问题,依次是:
为什么在参数有效的情况下打印用法?必须删除第一个 printf
在
if (argc != 2)
printf("usage: %s l(ower)/u(pper)", argv[0]);
你检测参数的数量是否错误,但在这种情况下你打印用法并继续,如果那个数字是正确的,所以如果你调用你的程序没有参数你将调用 strcmp
与 NULL作为第一个参数,具有未定义的行为
在
else
printf("usage: %s l(ower)/u(pper)", argv[0]);
如果参数不是 l/lower/u 或你在 else 情况下输入的参数,但在其中打印用法并再次继续,就像没有错误一样,所以在那种情况下 convert 没有被初始化,当你使用它来调用转换函数时,行为将是不确定的。
一种方法是:
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
int main(int argc, char *argv[])
{
int (*convert)(int c) = NULL;
if (argc == 2) {
if (strcmp(argv[1], "l") == 0 || strcmp(argv[1], "lower") == 0)
convert = tolower;
else if(strcmp(argv[1], "u") == 0 || strcmp(argv[1], "upper") == 0)
convert = toupper;
}
if (convert == NULL)
printf("usage: %s l(ower)/u(pper)\n", argv[0]);
else {
int c;
while ((c = getchar()) != EOF)
putchar(convert(c));
}
return 0;
}
编译与执行:
pi@raspberrypi:/tmp $ gcc -g -Wall cv.c
pi@raspberrypi:/tmp $ ./a.out
uasge: ./a.out l(ower)/u(pper)
pi@raspberrypi:/tmp $ ./a.out a z
uasge: ./a.out l(ower)/u(pper)
pi@raspberrypi:/tmp $ ./a.out z
uasge: ./a.out l(ower)/u(pper)
pi@raspberrypi:/tmp $ ./a.out u
a
A
P
P
(
(
如果您 运行 代码没有参数,或者参数不正确,printf 语句会告诉您这一点,但是程序继续 运行ning,所以您可能正在调用 'convert' 函数指针,同时它仍然设置为 NULL。在您看到消息告诉您您没有为程序提供正确的参数之前,这将崩溃。
您可能想在打印语句告诉您参数丢失或不正确之后放置 'return 1' 或其他内容。如果这样做,您需要将整个 'if' 或 'else' 子句放在方括号中,否则 return 语句将无条件执行。
您的缩进样式有点不标准。也许这就是为什么您忽略了这样一个事实,即在 'printf 告诉您程序未正确 运行 之后没有 'return' 语句。
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
int main(int argc, char *argv[])
{
printf("usage: %s l(ower)/u(pper)", argv[0]);
int (*convert)(int c) = NULL;
int c;
if (argc != 2) {
printf("uasge: %s l(ower)/u(pper)", argv[0]);
return 1;
}
if (strcmp(argv[1], "l") == 0 || strcmp(argv[1], "lower") == 0) {
convert = tolower;
} else if(strcmp(argv[1], "u") == 0 || strcmp(argv[1], "upper") == 0) {
convert = toupper;
} else {
printf("uasge: %s l(ower)/u(pper)", argv[0]);
return 1;
}
while ((c = getchar()) != EOF)
putchar((*convert)(c));
return 0;
}
这是我的全部源代码:
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
int main(int argc, char *argv[])
{
printf("usage: %s l(ower)/u(pper)", argv[0]);
int (*convert)(int c) = NULL;
int c;
if (argc != 2)
printf("usage: %s l(ower)/u(pper)", argv[0]);
if (strcmp(argv[1], "l") == 0 || strcmp(argv[1], "lower") == 0)
convert = tolower;
else if(strcmp(argv[1], "u") == 0 || strcmp(argv[1], "upper") == 0)
convert = toupper;
else
printf("usage: %s l(ower)/u(pper)", argv[0]);
while ((c = getchar()) != EOF)
putchar((*convert)(c));
return 0;
}
我用 cc 编译这段代码,运行 在 MacBook 上编译。 收到分段错误。
你的代码有几个问题,依次是:
为什么在参数有效的情况下打印用法?必须删除第一个 printf
在
if (argc != 2) printf("usage: %s l(ower)/u(pper)", argv[0]);
你检测参数的数量是否错误,但在这种情况下你打印用法并继续,如果那个数字是正确的,所以如果你调用你的程序没有参数你将调用 strcmp
与 NULL作为第一个参数,具有未定义的行为
在
else printf("usage: %s l(ower)/u(pper)", argv[0]);
如果参数不是 l/lower/u 或你在 else 情况下输入的参数,但在其中打印用法并再次继续,就像没有错误一样,所以在那种情况下 convert 没有被初始化,当你使用它来调用转换函数时,行为将是不确定的。
一种方法是:
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
int main(int argc, char *argv[])
{
int (*convert)(int c) = NULL;
if (argc == 2) {
if (strcmp(argv[1], "l") == 0 || strcmp(argv[1], "lower") == 0)
convert = tolower;
else if(strcmp(argv[1], "u") == 0 || strcmp(argv[1], "upper") == 0)
convert = toupper;
}
if (convert == NULL)
printf("usage: %s l(ower)/u(pper)\n", argv[0]);
else {
int c;
while ((c = getchar()) != EOF)
putchar(convert(c));
}
return 0;
}
编译与执行:
pi@raspberrypi:/tmp $ gcc -g -Wall cv.c
pi@raspberrypi:/tmp $ ./a.out
uasge: ./a.out l(ower)/u(pper)
pi@raspberrypi:/tmp $ ./a.out a z
uasge: ./a.out l(ower)/u(pper)
pi@raspberrypi:/tmp $ ./a.out z
uasge: ./a.out l(ower)/u(pper)
pi@raspberrypi:/tmp $ ./a.out u
a
A
P
P
(
(
如果您 运行 代码没有参数,或者参数不正确,printf 语句会告诉您这一点,但是程序继续 运行ning,所以您可能正在调用 'convert' 函数指针,同时它仍然设置为 NULL。在您看到消息告诉您您没有为程序提供正确的参数之前,这将崩溃。 您可能想在打印语句告诉您参数丢失或不正确之后放置 'return 1' 或其他内容。如果这样做,您需要将整个 'if' 或 'else' 子句放在方括号中,否则 return 语句将无条件执行。 您的缩进样式有点不标准。也许这就是为什么您忽略了这样一个事实,即在 'printf 告诉您程序未正确 运行 之后没有 'return' 语句。
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
int main(int argc, char *argv[])
{
printf("usage: %s l(ower)/u(pper)", argv[0]);
int (*convert)(int c) = NULL;
int c;
if (argc != 2) {
printf("uasge: %s l(ower)/u(pper)", argv[0]);
return 1;
}
if (strcmp(argv[1], "l") == 0 || strcmp(argv[1], "lower") == 0) {
convert = tolower;
} else if(strcmp(argv[1], "u") == 0 || strcmp(argv[1], "upper") == 0) {
convert = toupper;
} else {
printf("uasge: %s l(ower)/u(pper)", argv[0]);
return 1;
}
while ((c = getchar()) != EOF)
putchar((*convert)(c));
return 0;
}