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;
}