为什么scanf没有正确读取值?

时间:2013-09-16 07:35:04

标签: c unix compiler-construction printf scanf

有人可以告诉我这里出了什么问题吗?

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

#define ERROR 0
#define MAX_INPUT_LINE 80
#define print(x) {fputs(x,stdout);}
#define SUCCESS 1

int main (long argc, char *argv[])
{
   int mode;
   printf("1 for hexidecimal or 2 for binary");
   scanf("%d", mode);

   printf("\n\n\nThe value of mode is %d\n", mode);
   return 0;
}

当我为二进制文件输入 2 时,我得到了这个:

The value of mode is 2665564

显然我应该得到2,我做错了什么?是我的编译器,是因为我使用的是Cygwin?为什么模式不是2 ??

9 个答案:

答案 0 :(得分:7)

你的scanf错了。应该是:

scanf("%d", &mode);

&告诉编译器将scanf 指针发送到mode(即其地址),而不是mode的实际值。这样scanf可以将更新mode与新的扫描值放在一起。

答案 1 :(得分:4)

这是C,而不是Java。当您使用像scanf (...)这样的函数,因为您无法通过引用传递变量时,您应该将指针传递给将保存该值的变量。

请改用以下内容:

scanf ("%d", &mode);

使用(&amp;)将传递模式的地址,而不是隐式地将模式转换为(int *)

在这个例子中你真的很幸运,这不会导致你的程序崩溃。如果mode的值为0并且为了满足此函数而被强制转换为指针,那么最好取消引用NULL指针。

答案 2 :(得分:2)

您使用scanf错误。对于整数值,浮点值或字符等内容,您需要为要填充的变量提供指针。使用address-of运算符&最容易完成,就像

一样
scanf("%d", &mode);

scanf系列函数在读取字符串时也需要一个指针,但由于字符串指针(或衰减到指针的数组),因此不需要地址 - 字符串的运算符。

我建议您阅读this scanf reference,因为它包含一个表格,显示不同格式代码所期望的参数。

答案 3 :(得分:2)

scanf的第二个参数是错误的,它需要指针int,因为格式为%d

scanf("%d", &mode);
//          ^

答案 4 :(得分:2)

scanf接受指针,然后尝试将值放在指针指向的位置,这意味着您无法发送mode需要发送&mode。发送mode将导致未定义的行为。

DO

scanf ("%d", &mode);

您的完整代码:

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

#define ERROR 0
#define MAX_INPUT_LINE 80
#define print(x) {fputs(x,stdout);}
#define SUCCESS 1

int main (long argc, char *argv[])
{
   int mode;
   printf("1 for hexidecimal or 2 for binary");
   scanf("%d", &mode);

   printf("\n\n\nThe value of mode is %d\n", mode);
   return 0;
}

我还要说明如果要以十六进制模式打印数字,请使用%x

printf("%x", mode);

答案 5 :(得分:2)

scanf的附加参数是一个地址。参考here

顺便说一句,附加参数应该指向已经分配的格式字符串中由其相应格式说明符指定的类型的对象。

所以只需将main()中的第3行更改为:

scanf("%d", &mode);

答案 6 :(得分:1)

你很幸运,你的程序不会因内存故障而崩溃。由于mode未初始化,因此其值未定义,因此您在随机地址存储整数。

稍后,您将以十进制格式打印该地址。

这应该“有效”(如果编译器接受):

printf("%d\n",*mode);

printf("%d\n",*(int*)mode);

为了澄清,我显然不建议取消引用未初始化的指针。我只是想解释为什么程序没有崩溃,并显示如何通过保持伪造scanf原样获得输入的值(不同于正确修复根本原因的所有其他回复)。在32位环境中,int和指针都存储在4个字节中,因此CPU无法区分。当然编译器至少应该输出带有这种虚假代码的警告。

答案 7 :(得分:1)

scanf原型是int scanf(const char * format,...);因此使用'&amp;'发送地址......

答案 8 :(得分:1)

您的代码应该是这样的:

scanf("%d", &mode);

您错过了代码中的&符号。