格式指定类型为'char *',但参数为类型'char'[-Wformat] [英] format specifies type 'char *' but the argument has type 'char' [-Wformat]

查看:92
本文介绍了格式指定类型为'char *',但参数为类型'char'[-Wformat]的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am attempting to check and output the command line arguments given for a specific program "format.c" when called from the terminal. I am getting the following error and I do not understand what it is telling me. error: format specifies type 'char *' but the argument has type 'char' [-Wformat] here is my code thus far:

#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(这是取消引用的作用,删除一颗星)。
因此,函数期望使用指向char的指针,但是它得到了char。错误。

printArguments function expects arguments of type int and char **. That is what argc and argv already are. If you type **argv, you are dereferencing pointer twice. So, you are doing char ** => char * => char (this is what dereferencing does, "removes" one star). So, function expects pointer to a pointer to a char, but it gets a char. Wrong.

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

Secondly, to explain the mistake with *argv[i], one has to understand how C programmer stores its data. Firstly, C program is given some internal memory that is divided in four segments: stack segment, data segment, heap segment and code segment. Data segments stores global variables, code segment stores program's code. Heap segment stores dynamically allocated variables. They do not have their names, and one retrieves data by it's address in memory. This is done with argv[i] i.e. *(argv+i). This is exactly the same thing, just another syntax.

因此,让我们概述一下某些数据结构如何存储在内存中:

1. int a [5] 是5个整数的数组。如果不是全局数组,则将其存储在堆栈中。使用此声明,内存中将占用20个字节。我们最多可以在此数组中保存5个整数或更少,但不能更多。
2. int * p = NULL 是一个指针。它可以指向整数。使用此初始化,它指向无处。当我们说变量指向某处时,意味着它不包含确切的数据(数字,字符),而是一个包含该数据的地址。
3. int * p =(int *)malloc(sizeof(int)* 5)是一个指向五个整数中第一个整数的变量,即在五个整数数组的堆段中包含一个地址。因此,* p< => *(p + 0)< => p [0]。您可以通过在数组内部四处移动指针来形象地看到它。因此,p具有第一个地址。我们使用一些指针算术来检索其他对象。

So, let's overview how certain data structures are stored in memory: 1. int a[5] is an array of 5 integers. If not global array, it is stored on stack. With this declaration, 20 Bytes are occupied in memory. We can save up to 5 integers in this array or less, but not more. 2. int *p = NULL is a pointer. It can point to an integer. With this initialization, it points nowhere. When we say that variable "points" at somewhere, we mean that it does not contain an exact data (number, character) but an address where this data is. 3. int *p = (int *) malloc (sizeof(int) * 5) is a variable that points at the first of five integers, i.e. it contains an address in the heap segment of the array of five integers. So, *p <=> *(p+0) <=> p[0]. You can visualize this by moving pointers around inside the array. So, p has the address of the first one. We retrieve others using some "pointers arithmetic".


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

4. int a[3][5] is a statically allocated two dimensional array. It is an array which elements are also arrays. Since it is not dynamically allocated, it is stored on stack or data segment (depending on where it is declared, inside or outside of some function). 5. int *a[5] is an array of pointers. So, firstly there is a statically allocated array (stack/data segment). Afterwards, we can dynamically allocate member arrays (but they will be on heap). 6. int **a is a pointer to a pointer. So, a contains an address of a place that also has an address where some integer is stored. So, a points to a place that also points to a place with the integer. After step b) we said it should point to first of the five integers in the array (of course, in heap). What are members of this array? We said that a points to something that also points to something, so members are also pointers. We can say where these pointers point now. This is done after step c).

最后,

与字符相同整数的情况。
7.就像情况1(但您可以看到我们为'\0'节省了一个额外的字节)
8.就像情况5
的情况char ** 就像情况6。

(*)情况就是您 int argc的方式 char ** argv 看起来像。
这些是 main()函数的参数,因此存储在该函数的堆栈框架中。 argv 是指向第一个也是指针的元素的指针,指向字符数组中的第一个字符[说 argv 是字符数组的数组,如果我们有 char argv [50] [50] ,则为真;如果说 argv 是一个指针数组,那将是错误的,那就是 char * argv [50] ) 。因此, argv 是指向第一个字符的n个指针中第一个的指针。

And the (*) case is how your int argc and char **argv look like. These are arguments to the main() function, and are therefore stored in the stack frame for it. argv is pointer that points to the first of the elements that are also pointers, pointing to fist character in arrays of characters[it would be wrong to say that argv is 'array of arrays of chars', that would be true if we had char argv[50][50]; it would be wrong to say that argv is an array of pointers, that would be char *argv[50]). So, argv is pointer that points to the first of n pointers that point to first chars.

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

So, finally, argv[i] <=> *(argv+i) [this is how we retrieve ith pointer] That means *argv[i] <=> *(*(argv+i)) [this is how we retrieve where the ith pointer points at. It points at the first character of the ith argument!]

因此, argv [i] 的类型为 char * * argv [i] 的类型为 char 。您尝试使用%s 打印自变量,即 printf()期望字符串即字符数组即一个字符序列中的第一个字符的地址(这是C中的数组实际存储的),而不仅仅是一个实际的字符。

So, argv[i] is of type char *, and *argv[i] is of type char. You have tried to print argument with %s i.e. printf() expects "string" i.e. "array of chars" i.e. THE ADDRESS of the first char in a sequence of chars (which is what arrays in C actually store) and not just an actuall char.

我希望这会有所帮助。 :)

I hope this helps. :)

这篇关于格式指定类型为'char *',但参数为类型'char'[-Wformat]的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆