format 指定类型 'char *' 但参数的类型为 'char' [-Wformat]

format specifies type 'char *' but the argument has type 'char' [-Wformat]

我正在尝试检查并输出从终端调用时为特定程序 "format.c" 提供的命令行参数。我收到以下错误,我不明白它在告诉我什么。 错误: 格式指定类型 'char *' 但 参数的类型为 'char' [-Wformat] 到目前为止,这是我的代码:

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

int printArguments( int argc, char **argv )
{
    int i;
    printf( "Total number of arguments: %d", argc );
    for( i = 0; i <= argc; i++ ){
        printf( "argv[%d] = %s\n", i, *argv[i] );
    }
    return 0;
}

int main ( int argc, char **argv )
{
    if( argc != 3 ){
        puts( "You failed to enter the correct number of arguments." );
        printf( "You entered: \nargv[0] = %s\nargv[1] = %s\nargv[2] = %s\n",
               argv[0], argv[1], argv[2] );
        puts( "Argument format should be, \"./format (arg1 = int value)"
             "(arg2 = file name)\"\n" );
        return 0;
    }
    if( atoi(argv[1]) < 25 ){
        printf( "\nargv[1] = %d\nYou entered a value too small for the format\n",
        atoi(argv[1]) );
        return 0;
    }
    if( atoi(argv[1]) > 100 ){
        printf( "\nargv[1] = %d\nYou entered a value too large for the           format\n",
        atoi(argv[1]) );
        return 0;
    }

    printArguments( argc, **argv );

    return 0;
} /*end of main */

尝试

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

int printArguments( int argc, char **argv )
{
    int i;
    printf( "Total number of arguments: %d", argc );
    for( i = 0; i <= argc; i++ ){
        printf( "argv[%d] = %s\n", i, *(argv+i) );
    }
    return 0;
}

int main ( int argc, char **argv )
{
    if( argc != 3 ){
        puts( "You failed to enter the correct number of arguments." );
        printf( "You entered: \nargv[0] = %s\nargv[1] = %s\nargv[2] = %s\n",
               argv[0], argv[1], argv[2] );
        puts( "Argument format should be, \"./format (arg1 = int value)"
             "(arg2 = file name)\"\n" );
        return 0;
    }
    if( atoi(argv[1]) < 25 ){
        printf( "\nargv[1] = %d\nYou entered a value too small for the format\n",
        atoi(argv[1]) );
        return 0;
    }
    if( atoi(argv[1]) > 100 ){
        printf( "\nargv[1] = %d\nYou entered a value too large for the           format\n",
        atoi(argv[1]) );
        return 0;
    }

    printArguments( argc, argv );

    return 0;
} /*end of main */

更正如下: printArguments( argc, argv );printf( "argv[%d] = %s\n", i, *(argv+i) );

[编辑] printArguments 函数需要 intchar ** 类型的参数。 argcargv 已经是这样了。如果您键入 **argv,您将取消引用指针两次。所以,你正在做 char ** => char * => char(这就是取消引用的作用,"removes" 一颗星)。 因此,函数期望指向指向 char 的指针,但它得到的是 char。错了。

其次,要解释*argv[i]的错误,必须了解C程序员如何存储其数据。首先,给C程序一些内存,内存分为四个段:堆栈段、数据段、堆段和代码段。数据段存放全局变量,代码段存放程序代码。堆段存储动态分配的变量。他们没有自己的名字,一个人通过它在内存中的地址检索数据。这是通过 argv[i] 即 *(argv+i) 完成的。这完全是一回事,只是另一种语法。

那么,让我们概述一下某些数据结构是如何存储在内存中的: 1. int a[5] 是一个包含 5 个整数的数组。如果不是全局数组,则存储在堆栈中。通过这个声明,20 Bytes 被占用在内存中。我们最多可以在此数组中保存 5 个或更少的整数,但不能更多。 2. int *p = NULL 是一个指针。它可以指向一个整数。通过此初始化,它无处可去。当我们在某处说变量 "points" 时,我们的意思是它不包含确切的数据(数字、字符),而是包含该数据所在的地址。 3. int *p = (int *) malloc (sizeof(int) * 5) 是一个变量,指向五个整数中的第一个,即它包含一个地址在五个整数数组的堆段中。所以,*p <=> *(p+0) <=> p[0]。您可以通过在数组内部四处移动指针来形象化这一点。因此,p 具有第一个地址。我们使用一些 "pointers arithmetic".

检索其他人

4. int a[3][5]是一个静态分配的二维数组。它是一个数组,其元素也是数组。由于它不是动态分配的,它存储在堆栈或数据段中(取决于它的声明位置,在某个函数的内部或外部)。 5. int *a[5] 是一个指针数组。因此,首先有一个静态分配的数组(stack/data 段)。之后,我们可以动态分配成员数组(但它们将在堆上)。 6、int **a是指向指针的指针。因此,a 包含一个地方的地址,该地址也有一个存储某些整数的地址。所以,a 指向一个地方,也指向一个有整数的地方。 在步骤 b) 之后,我们说它应该指向数组中五个整数中的第一个(当然,在堆中)。这个数组的成员是什么?我们说 a 指向某物,也指向某物,所以成员也是指针。我们现在可以说出这些指针指向的位置。这是在步骤 c) 之后完成的。

最后, 对于字符,我们的情况与整数相同。 7. 与情况 1 类似(但您可以看到我们为 '\0' 节省了一个额外的字节) 8. 类似于案例 5 char ** 的案例与案例 6 类似。

(*) 是您的 int argcchar **argv 的样子。 这些是 main() 函数的参数,因此存储在它的堆栈帧中。 argv是指针,指向第一个也是指针的元素,指向字符数组中的第一个字符[说argv是'array of arrays of chars'是错误的,那会如果我们有 char argv[50][50] 则为真;说 argv 是一个指针数组是错误的,应该是 char *argv[50])。因此,argv 是指向第一个字符的 n 个指针中第一个的指针。

所以,最后,argv[i] <=> *(argv+i) [这就是我们检索第 i 个指针的方式] 这意味着 *argv[i] <=> *(*(argv+i)) [这就是我们检索第 i 个指针指向的位置的方式。它指向第i个参数的第一个字符!]

所以,argv[i]char *类型,*argv[i]char类型。您已尝试使用 %s 打印参数,即 printf() 期望 "string" 即 "array of chars" 即字符序列中第一个字符的地址(实际上是 C 中的数组store) 而不仅仅是一个实际的字符。

希望对您有所帮助。 :)

您应该将 argv[i] 而不是 *argv[i] 传递给 printArguments 中的 printf,因为 argv 的类型是 char **。所以 argv[i]char * 类型,*argv[i]char 类型。 printf%s 说明符需要一个 char * 参数。

出于同样的原因,您还应该将 argv 作为参数传递给 printArguments,而不是 **argv。您想要传递整个参数列表,而不是指向第一个参数的第一个字符的指针。我很惊讶你也没有收到警告。