printf%s segfaulting - 为什么?

时间:2018-03-16 06:07:02

标签: c segmentation-fault format-specifiers

我希望这会是我的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] segfaulting上有printf(“%s”)。

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

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

编辑1:

感谢您的指导。 TIL,printf("%s\n", argv[1][a-1]);是segfaulting,因为printf中的%s格式规范要求相应的参数为空终止的char数组。

(1)传递一个指针:

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

或,as:

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

或者,(2)使用char:

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

4 个答案:

答案 0 :(得分:5)

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

根据printf

  

<强>取值

     

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

答案 1 :(得分:3)

因为argv[1][a-1]char值,%c没有问题,而char数组的地址不能终止%s

答案 2 :(得分:2)

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

答案 3 :(得分:0)

在第二行,你必须写%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] );
    }