18

To read an int using scanf we use:

scanf("%d", &i);

What if i is a long not int??

Note: when using %d with long it gives me an irritating warning..

Betamoo
  • 14,964
  • 25
  • 75
  • 109
  • 1
    @Clifford: Show me where on that page it says it is an error if the pointer type does not match what is expected? Sure, if you properly grok memory access and how this function works, it is obvious that "should point to ... objects of the type specified by their corresponding format tag" is a strong "should", but it is not immediately obvious otherwise. Out of curiosity, I googled "man scanf"... the first link says "must" instead of "should", which is better, but then when describing the `d` flag, it says "the next pointer must be a pointer to int" with no mention of the possible modifiers. – Dennis Zickefoose Jun 21 '11 at 16:12
  • @Dennis; apart from the fact that this question is over a year old and my comment never raised comment until now, `long` is not a modifier of `int` it is a data type in its own right - even when written `long int`. The %d format specifier *does* have 'modifiers' for different size integer types, and those *are* documented in the link I gave. By implication if there is a specific format specifier for `long` ("%ld"), then the format specifier intended for `int` would be incorrect, otherwise there would be no need for the different format specifier. – Clifford Jun 21 '11 at 20:55

5 Answers5

35

Just use

long l;

scanf("%ld", &l);

it gives me an irritating warning..

That warning is quite right. This is begging for stack corruption.

jpalecek
  • 47,058
  • 7
  • 102
  • 144
  • Whereas your code simply gives undefined behaviour. You need to give scanf the address of the variable being read into. –  May 17 '10 at 20:19
  • jpalecek does do that with `&l` (unless the question has been edited after you left the comment) – adrian Mar 06 '19 at 06:48
8

For gods sake:

long n;
scanf( "%ld", & n );
  • 2
    To add to Neil's answer, you can't rely on something like "%d" to read a `long int` because that specifies an `int` rather than a `long (int)`. Not only that, `int` on some 64-bit systems is 32 bits in size while `long (int)` is 64 bits in size. In other words, you'd be reading a 32-bit integer into what is meant to be a 64-bit storage location. An example would be reading 2147483649. Since the 32-bit value is read into a 64-bit location, the other 32 bits are left with whatever values were present, so you might get something like 6442450945 if you had 4294967296 stored in there originally. – Dustin May 17 '10 at 20:47
3
scanf("%ld", &i);

You can also use "%Ld" for a long long (and depending on your compiler, sometimes also "%lld").

Take a look at the Conversions section of the scanf man page for more. (Just Google it if your system doesn't have manpages).

Vineet
  • 2,103
  • 14
  • 9
  • And doesn't that same man page say that the things you are reading into need to be passed to scanf as pointers? –  May 17 '10 at 20:28
  • 1
    For `long long (int)`, "%lld" is standard (the "L" modifier is meant for `long double`, so "%Ld" isn't standard, though I don't doubt that some implementations allow it). BSD flavours once used the "q" length modifier for a "quadword", which is just a 64-bit value, and I'm reasonably sure it is still accepted in some BSD-based implementations. Microsoft created the "I64" and "I32" length modifiers to specify a 64-bit and a 32-bit integer respectively, so "%I64d" would be valid in that case. In other words, `long long` is a mess of confusion when it comes to the formatted I/O functions. :P – Dustin May 17 '10 at 20:59
3

Each conversion specifier expects its corresponding argument to be of a specific type; if the argument's type does not match the expected type, then the behavior is undefined. If you want to read into a long with scanf(), you need to use the %ld conversion specifier:

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

Check the online draft C standard (.pdf file), section 7.19.6.2, paragraph 11 for a complete listing of size modifiers and expected types.

John Bode
  • 119,563
  • 19
  • 122
  • 198
-1

Check this, here is the answer: "%I64d"

eldarerathis
  • 35,455
  • 10
  • 90
  • 93