【问题标题】: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>&</i></b>someVar) 将传递someVar 变量的地址(使用& 一元运算符)。
scanf 函数会将一个数字放入该地址的内存块中。 (其中包含您的变量)
当您编写scanf("%d", age) 时,您将age 变量的值 传递给scanf。它会尝试将一个数字放入地址为0 的内存中(因为age 是0),然后搞得一团糟。
您需要将&age 传递给scanf。
您还需要为scanf 分配内存以将字符串读入name:
char name[100];
scanf("%99s\n", name);
【解决方案2】:
您应该写scanf("%d", &age),因为scanf 函数需要修改 age 的值,因此需要“按地址”而不是“按值”传递它。
【解决方案3】:
这意味着它需要一个“int *”(即:指向整数的指针),但你给它一个整数“int”。要修复它,请将 & 添加到 scanf 行中的年龄,使其变为。
scanf("%d\n", 年龄);
【解决方案4】:
我假设它抱怨scanf("%d\n", age); 行问题是 scan f 需要一个指向您的变量而不是变量的指针。您需要通过附加一个'&`来获取变量的地址,你应该没问题。
【解决方案5】:
警告的含义与它所说的完全一样:编译器在 scanf 调用中需要一个指向 int 而不是 int 的指针。
快速修复:将age 替换为&age,一切正常。
C 通过值传递所有参数,这意味着如果您传递一个变量,则仅传递该变量的值。接收函数可以随心所欲地修改该值,但原始值不会改变。要更改变量,您需要以某种方式传递一个指向该变量的值,在 C 中是一个指针。
要获得指向变量的指针,请在其前面加上 &。要使用有指针指向的变量,请在指针值前面加上 *。
在这种情况下,您希望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() 函数时,请始终牢记这些内容,因为您不会在代码中遇到问题。
感谢您提出这个问题,因为我以后在编写这种类型的代码时也不会犯这样的错误。