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
函数需要 int
和 char **
类型的参数。 argc
和 argv
已经是这样了。如果您键入 **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 argc
和 char **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
。您想要传递整个参数列表,而不是指向第一个参数的第一个字符的指针。我很惊讶你也没有收到警告。
我正在尝试检查并输出从终端调用时为特定程序 "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
函数需要 int
和 char **
类型的参数。 argc
和 argv
已经是这样了。如果您键入 **argv
,您将取消引用指针两次。所以,你正在做 char ** => char * => char(这就是取消引用的作用,"removes" 一颗星)。
因此,函数期望指向指向 char 的指针,但它得到的是 char。错了。
其次,要解释*argv[i]的错误,必须了解C程序员如何存储其数据。首先,给C程序一些内存,内存分为四个段:堆栈段、数据段、堆段和代码段。数据段存放全局变量,代码段存放程序代码。堆段存储动态分配的变量。他们没有自己的名字,一个人通过它在内存中的地址检索数据。这是通过 argv[i] 即 *(argv+i) 完成的。这完全是一回事,只是另一种语法。
那么,让我们概述一下某些数据结构是如何存储在内存中的:
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".
int a[3][5]
是一个静态分配的二维数组。它是一个数组,其元素也是数组。由于它不是动态分配的,它存储在堆栈或数据段中(取决于它的声明位置,在某个函数的内部或外部)。
5. int *a[5]
是一个指针数组。因此,首先有一个静态分配的数组(stack/data 段)。之后,我们可以动态分配成员数组(但它们将在堆上)。
6、int **a
是指向指针的指针。因此,a
包含一个地方的地址,该地址也有一个存储某些整数的地址。所以,a
指向一个地方,也指向一个有整数的地方。
在步骤 b) 之后,我们说它应该指向数组中五个整数中的第一个(当然,在堆中)。这个数组的成员是什么?我们说 a
指向某物,也指向某物,所以成员也是指针。我们现在可以说出这些指针指向的位置。这是在步骤 c) 之后完成的。
最后,
char **
的案例与案例 6 类似。
(*) 是您的 int argc
和 char **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
。您想要传递整个参数列表,而不是指向第一个参数的第一个字符的指针。我很惊讶你也没有收到警告。