【问题标题】:warning: format ‘%d’ expects type ‘int *’, but argument 2 has type ‘int’警告:格式“%d”需要类型“int *”,但参数 2 的类型为“int”
【发布时间】:2011-06-12 16:40:28
【问题描述】:

所以我是 C 的新手,并且对这个警告发生的事情有疑问。警告是什么意思,我该如何解决。 我写的代码在这里:

void main(void)
{
  char* name = "";
  int age = 0;
  printf("input your name\n");
  scanf("%s\n", name);
  printf("input your age\n");
  scanf("%d\n", age);
  printf("%s %d\n", name, age);

}

【问题讨论】:

    标签: c compiler-construction warnings


    【解决方案1】:

    scanf 函数将变量的地址 放入其中。
    写入scanf("%d", <b><i>&amp;</i></b>someVar) 将传递someVar 变量的地址(使用&amp; 一元运算符)。
    scanf 函数会将一个数字放入该地址的内存块中。 (其中包含您的变量)

    当您编写scanf("%d", age) 时,您将age 变量的 传递给scanf。它会尝试将一个数字放入地址为0 的内存中(因为age0),然后搞得一团糟。

    您需要将&amp;age 传递给scanf

    您还需要为scanf 分配内存以将字符串读入name

    char name[100];
    scanf("%99s\n", name);
    

    【讨论】:

      【解决方案2】:

      您应该写scanf("%d", &amp;age),因为scanf 函数需要修改 age 的值,因此需要“按地址”而不是“按值”传递它。

      【讨论】:

        【解决方案3】:

        这意味着它需要一个“int *”(即:指向整数的指针),但你给它一个整数“int”。要修复它,请将 & 添加到 scanf 行中的年龄,使其变为。

        scanf("%d\n", 年龄);

        【讨论】:

          【解决方案4】:

          我假设它抱怨scanf("%d\n", age); 行问题是 scan f 需要一个指向您的变量而不是变量的指针。您需要通过附加一个'&`来获取变量的地址,你应该没问题。

          【讨论】:

            【解决方案5】:

            警告的含义与它所说的完全一样:编译器在 scanf 调用中需要一个指向 int 而不是 int 的指针。

            快速修复:将age 替换为&amp;age,一切正常。

            C 通过值传递所有参数,这意味着如果您传递一个变量,则仅传递该变量的值。接收函数可以随心所欲地修改该值,但原始值不会改变。要更改变量,您需要以某种方式传递一个指向该变量的值,在 C 中是一个指针。

            要获得指向变量的指针,请在其前面加上 &amp;。要使用有指针指向的变量,请在指针值前面加上 *

            在这种情况下,您希望scanf 更改age 的值,因此您需要传递一个指针。

            【讨论】:

              【解决方案6】:
              char* name = "";
              

              name 指向足以容纳单个空字符的位或内存。

              scanf("%s\n", name);
              

              您要求在此地址读取和存储未知数量的字符。 任何事情都可能发生。您必须确保 name 拥有足够大的内存块的地址,以容纳 scanf() 可能读取的任何内容。

              char twenty_bytes[20] = "";
              scanf("%s\n", twenty_bytes);
              

              【讨论】:

                【解决方案7】:

                问题出在这一行:

                scanf("%d\n", age);
                

                scanf 需要指针参数 - 这是函数在 C 中修改参数的唯一方法。为了解决这个问题,您需要:

                scanf("%d\n", &age);
                

                其中传递了age的地址,现在是一个指针(指针是一个变量,包含指向另一个内存区域的地址)。

                至于这个:

                char* name = "";
                

                哎哟-请-不要!好的,我需要解释一下。你要求一个指向字符类型的指针,但就每个人而言,你所拥有的只是一个字符,而不是整个字符串。没错,就是空间不够。为什么 C 让你这样做?好吧,C 基本上是可移植的汇编程序,因此您可以在内存中任意编写(或者更确切地说,您可以尝试,编译器不会不同意,但操作系统可以并且可能会)。

                您需要做的是使用malloc 读取内存分配以分配一些空间,否则我可以输入一个大字符串并将其放在名称的地址之前。

                这可能,尽管绝不会导致基于堆栈的漏洞。什么,堆栈? 是的。堆栈是一种 FILO 结构,每次调用函数时,都会在堆栈上添加空间,用于存储返回地址和函数参数,以及通常的函数范围变量。

                如果您不检查输入大小,就会出现问题。然后,我可以将大量值写入您的堆栈,包括可执行代码...参见Buffer Overflow

                那么我该如何缓解这种情况,我听到你说,只是渴望不实施软件漏洞?您使用允许您指定缓冲区输入大小并读入特定大小的缓冲区的函数,然后从那里开始。而已。就这么简单。

                看到这个问题:string reading in C

                【讨论】:

                  【解决方案8】:

                  嘿朋友最近的意思是今天我也经历了这些东西。不用担心它很简单。

                  以下代码行中的问题:

                  scanf("%s\n", name);
                  

                  scanf("%d\n", age);
                  

                  您只需像 printf() 函数一样编写这些行。如果您使用的是 scanf() 函数,那么请始终在 scanf() 函数 中的变量之前使用 ampersand(&),因为这是必要的。 &'Address of '操作符,它给出了变量使用的数字(地址)在内存中的位置。

                  您更正的代码行:

                  scanf("%s\n", &name);
                  

                  scanf("%d\n", &age);
                  

                  下次您要编写此类代码或使用 scanf() 函数时,请始终牢记这些内容,因为您不会在代码中遇到问题。

                  感谢您提出这个问题,因为我以后在编写这种类型的代码时也不会犯这样的错误。

                  【讨论】:

                    猜你喜欢
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    • 2019-04-03
                    • 2015-02-27
                    • 1970-01-01
                    • 2013-04-22
                    • 1970-01-01
                    • 1970-01-01
                    相关资源
                    最近更新 更多