2010-05-17 131 views
12

要使用scanf函数读取一个int我们使用:scanf函数的C/C++

scanf("%d",&i); 

如果i早已不是int?

注:使用%dlong它给了我一个警告的刺激性..

谢谢!

+4

“如果'i'长不是int ??” - 如果您阅读文档,该怎么办?标准库被有意识地记录下来(在许多地方)。永远不需要发布RTFM可以回答的问题。 http://www.cplusplus.com/reference/clibrary/cstdio/scanf/ – Clifford 2010-05-17 21:03:19

+1

@Clifford:请告诉我,如果指针类型与期望的不匹配,那么它在页面上的位置说明它是错误的?当然,如果你正确地理解了内存访问以及这个函数是如何工作的,那么很明显,“应该指向......它们相应的格式标签所指定的类型的对象”是一个强大的“应该”,但是它并不是很明显。出于好奇,我搜索了“man scanf”......第一个链接表示“必须”而不是“should”,这更好,但是当描述“d”标志时,它说“下一个指针必须是指针到int“,没有提到可能的修饰符。 – 2011-06-21 16:12:14

+0

@ Dennis;除了这个问题已超过一年之久,我的评论至今未提出评论,“long”并不是“int”的修饰符,它本身就是一种数据类型 - 即使写入“long int”时也是如此。 %d格式说明符*对不同大小的整数类型具有“修饰符”,这些*在我给出的链接中记录。通过暗示,如果对于'long'(“%ld”)有特定的格式说明符,那么用于'int'的格式说明符将不正确,否则就不需要不同的格式说明符。 – Clifford 2011-06-21 20:55:44

回答

20

只需使用

long l; 

scanf("%ld", &l); 

它给了我一个警告的刺激性..

这一警告是完全正确的。这是乞求堆栈损坏。

+0

而您的代码只是给出未定义的行为。你需要给scanf读入的变量地址。 – 2010-05-17 20:19:40

2
scanf("%ld", &i); 

您还可以使用"%Ld"long long(并根据你的编译器,有时也"%lld")。

查看更多的scanf手册页的Conversions部分。 (如果您的系统没有联机帮助页,只需Google即可)。

+0

并不是说同一个人的页面说你正在阅读的东西需要传递给scanf作为指针? – 2010-05-17 20:28:29

+1

对于'long long(int)',“%lld”是标准的(“L”修饰符是用于'long double'的,所以“%Ld”不是标准的,尽管我不怀疑某些实现允许它)。 BSD风格曾经使用“q”长度修饰符来表示一个“四字”,它只是一个64位的值,我相当肯定它在一些基于BSD的实现中仍然被接受。微软创建了“I64”和“I32”长度修饰符来分别指定一个64位和一个32位整数,所以“%I64d”在这种情况下是有效的。换句话说,当涉及格式化的I/O功能时,“long long”是一团混乱。 :P – Dustin 2010-05-17 20:59:43

6

对于神缘故:

long n; 
scanf("%ld", & n); 
+1

要添加到Neil的答案中,不能依赖类似于“%d”的内容来读取“long int”,因为它指定了一个“int”而不是“long(int)”。不仅如此,某些64位系统上的“int”大小为32位,而“long(int)”大小为64位。换句话说,你会读取一个32位整数来表示64位存储位置。一个例子是读取2147483649.由于32位值被读入64位位置,所以其他32位保留任何值,所以如果最初存储了4294967296,那么你可能得到类似6442450945的东西。 – Dustin 2010-05-17 20:47:20

3

每个转换指定期望其相应的参数是特定类型的;如果参数的类型与期望的类型不匹配,那么行为是未定义的。如果你想读入一个长着scanf(),您需要使用%ld转换说明:

long i; 
scanf("%ld", &i); 

检查在线draft C standard(.pdf文件),第7.19.6.2,第11段尺寸的完整列表修饰符和预期类型。

-1

请检查此处,这里是答案:“%I64d”

+4

除了作为非标准的扩展,在很多系统上'long'不是一个64位的类型。 – 2011-06-21 16:16:24