【问题标题】:format ‘%c’ expects argument of type ‘char *’, but argument 2 has type ‘char (*)[0]’格式“%c”需要“char *”类型的参数,但参数 2 的类型为“char (*)[0]”
【发布时间】:2020-02-13 03:27:47
【问题描述】:

我想创建一个程序,您可以在其中提供输入并根据输入提供输出,但我在输入部分遇到了一些问题。我首先制作了一个未初始化的字符串,并希望将输入存储在其中。但是当我编译时,它显示了这个错误:

格式“%c”需要“char *”类型的参数,但参数 2 的类型为“char (*)[0]”

我在网上查看过,但无法获得有关如何解决此问题的答案。

到目前为止我的代码如下(C 语言):

#include <stdio.h>
#include <stdlib.h>

int main() {
    char string[] = "";
    scanf("%c", &string);
}

【问题讨论】:

  • 你用的是什么编译器? gcc 和 clang 都说char (*)[1],而不是char (*)[0]。
  • 您确定不想要%s 吗?在任何情况下,请注意 string 变量声明的大小只有 1 个字节,因此除了空字符串之外不能存储任何有效字符串。
  • 您不应该收到此代码的消息,请检查您是否正在编译您发布的内容
  • 我使用的编译器是 gcc @Joseph

标签: c arrays


【解决方案1】:

&amp;string 是一个指向数组的指针,只需传递string 就足够了。 string 的长度为 1,适合单个字符,但不要试图将其解释为字符串,因为它不会以 null 结尾。

#include <stdio.h>
#include <stdlib.h>

int main() {
    char string[] = "";
    scanf("%c", string);
}

或者,您也可以这样做。它是等效的,有人说它更具可读性。

int main() {
    char string[] = "";
    scanf("%c", &string[0]);
}

【讨论】:

    【解决方案2】:

    您的问题陈述是“我想创建一个程序,您可以在其中提供输入并根据输入提供输出”

    你可以试试这样的:

    #include <stdio.h>
    #include <stdlib.h>
    
    #define MAX_LEN 50
    
    int main(){
        char string[MAX_LEN+1];
    
        //fgets is safe & would read whitespaces
        fgets(string, MAX_LEN, stdin);
        printf("%s", string);
        return 0;
    }
    

    【讨论】:

    • fgets(string, MAX_LEN, stdin) --> fgets(string, sizeof string, stdin)。 fgets() 函数读取的内容最多比指定的最大数量少一,为\0 终止符留出空间。
    【解决方案3】:

    关于;

    scanf("%c", &string);
    

    变量string 是一个数组。在 C 中,对数组的“裸”引用会降级为数组第一个字节的地址。因此,对scanf() 参数&amp;string 的调用正在询问地址的地址。

    通常编译器会输出警告(如您所见),但会生成正确的代码。为避免此问题,当参数是对数组的“裸”引用时,请从参数中删除 &amp;。即。

    scanf("%c", string);
    

    更好的是,使用:

    scanf("%c", &string[0]);
    

    对于健壮的代码,请始终检查任何scanf() 系列函数的返回值。通常,它们返回成功输入格式转换说明符的数量。所以一个更好的例子是;

    if( scanf("%c", &string[0]) != 1 )
    {
        fprintf( stderr, "scanf for first char of array -string- failed" );
    }
    

    这种错误(通常)是不可恢复的,所以通常代码是:

    if( scanf("%c", &string[0]) != 1 )
    {
        fprintf( stderr, "scanf for first char of array -string- failed" );
        exit( EXIT_FAILURE );
    }
    

    exit() 和 EXIT_FAILURE 都暴露在头文件中:stdlib.h

    【讨论】:

    • "对 scanf() 参数的调用 &amp;string 正在询问地址的地址" -- 在 C 中,数组表达式衰减为指向第一个元素的指针大多数表达式中数组的(不是第一个字节),但不是当它是一元&amp; 地址运算符的操作数时(或者当它是sizeof 的操作数时,或者当它是用于初始化的字符串文字时另一个数组)。因此,&amp;string 采用string[](数组)的地址,而不是指向第一个元素的指针的地址。错误消息通过argument 2 has type ‘char (*)[0]’ 抱怨此问题。
    • @exnihilo,请解决我的答案的可用性问题,不要被我如何表达细节的语义所束缚。另外,如果您认为数组中的“第一个字节的地址”和“第一个元素的地址”之间存在差异,请说明您认为存在差异的原因
    • 我的评论确实解决了您的答案的可用性问题。关于数组与指针和数组到指针衰减的误解在这个网站上比比皆是,答案在细节上应该是正确的。你的说法“&amp;string是要求地址”是绝对错误的,这种错误陈述只会给学习者带来麻烦。
    • 是的,第一个字节的地址和第一个元素的地址是一样的,但是数组不衰减到第一个字节的地址,而是衰减指向数组第一个元素的指针。这个指针不是指向第一个字节的指针,而是指向第一个元素的指针。区别在于指针的类型,当尝试进行指针运算时,您当然可以分辨出区别。
    • &amp;string 不是地址的地址。
    猜你喜欢
    • 2022-01-21
    • 1970-01-01
    • 1970-01-01
    • 2016-09-14
    • 2018-11-03
    • 2013-05-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多