【问题标题】:printf %s segfaulting - why?printf %s 段错误 - 为什么?
【发布时间】:2018-03-16 06:07:01
【问题描述】:

我希望这会 o/p 我的 argv[1] 的最后一个字母:

$ cat input_string_fu.c 
#include <stdio.h>

int main(int argc, char *argv[])
{
    if (argc !=2){
       printf("Error: Invalid syntax\n");
       return 1;
    };

    int a;
    a = strlen(argv[1]);
    if (a >= 2){
        printf("Last char of %s : %c\n", argv[1], argv[1][a-1] );
        printf("Last char of %s : %s\n", argv[1], argv[1][a-1] );
    } 
    return 0;
}

我很困惑为什么 argv[1][a-1] 上的 printf("%s") 会出现段错误。

$ ./a.out stackoverflow
Last char of stackoverflow : w
Segmentation fault
$ 

感谢您的时间和专业知识!

编辑 1:

感谢您的指导。 TIL,printf("%s\n", argv[1][a-1]); 出现了段错误,因为 printf 中的 %s 格式规范要求相应的参数是一个以空字符结尾的字符数组。

或者,(1) 传递一个指针:

printf("%s\n", &argv[1][a-1]);

或者,如:

char *ptr = argv[1];
printf("%s\n", &ptr[a-1]);

或者,(2) 使用字符:

printf("%c\n", argv[1][a-1]); 

【问题讨论】:

  • 使用不正确的格式说明符(在这种情况下为%s)是未定义的行为。
  • 如果您想使用 %s 打印最后一个字母,请传递一个指针(我看到的 4 个答案都没有建议):` printf("Last char of %s : %s\n ", argv[1], &argv[1][a-1]);`
  • 是什么让您认为可以使用两个不同的说明符打印相同类型的变量?
  • 如果您想从地址'w' 读取,您还有什么期望?
  • 你可能没有启用所有你应该启用的警告——好的编译器会帮助你发现这里的不匹配。对于 GCC,请尝试 -Wall -Wextra -Wwrite-strings -Wno-parentheses -Wpedantic -Warray-bounds 作为初学者(-Wall -Wextra 开启 -Wformat,这是您需要的)。

标签: c segmentation-fault format-specifiers


【解决方案1】:

因为%s 格式说明符用于字符串,但您尝试使用%s 打印字符。

根据printf

s

如果不存在 l 修饰符: const char * 参数是 预期的 成为指向字符类型数组的指针(指向字符串的指针)。 数组中的字符最多写入(但不包括)a 终止空字节('\0');如果指定了精度,则不再 比指定的数量被写入。如果给出精度,则不 需要存在空字节;如果未指定精度,或者是 大于数组的大小,数组必须包含一个 终止空字节。

【讨论】:

    【解决方案2】:

    因为argv[1][a-1]char 值,所以%c 可以,而不是char 数组的地址以零结尾,可用于%s

    【讨论】:

      【解决方案3】:

      第二个 printf "Last char of %s : %s\n" 的格式字符串需要一个指向以空字符结尾的字符串的指针作为第二个参数,同时您提供 char。

      【讨论】:

        【解决方案4】:

        在第二行你必须写%c 因为%s 需要const char * 参数 而你正在传递const char

         if (a >= 2){
                printf("Last char of %s : %c\n", argv[1], argv[1][a-1] );
                printf("Last char of %s : %c\n", argv[1], argv[1][a-1] );
            } 
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2018-06-06
          • 2017-01-17
          • 2015-01-05
          • 2021-11-06
          • 2021-01-27
          • 2014-05-09
          • 2010-09-07
          相关资源
          最近更新 更多