35

What is the difference between scanf and scanf_s? In the university I have been taught and I am using scanf, but at my personal computer Visual Studio keeps sending this warning.

 error C4996: 'scanf': This function or variable may be unsafe. Consider using scanf_s instead.

And I have to change all scanf to scanf_s or the program won't build. (I am using Visual Studio 2013)

a stone arachnid
  • 1,272
  • 1
  • 15
  • 27
Tony Andreev
  • 421
  • 1
  • 6
  • 9
  • 1
    possible duplicate of [Scanf\_s warning? Skips User Inputs (topics: Runge-Kutta, Epidemic Simulation)](http://stackoverflow.com/questions/9986776/scanf-s-warning-skips-user-inputs-topics-runge-kutta-epidemic-simulation) – Andreas Fester Jan 29 '14 at 15:01
  • 1
    It is the same as `scanf`, except it does not cause buffer overload. – David Ranieri Jan 29 '14 at 15:02
  • 1
    see http://msdn.microsoft.com/en-us/library/w40768et(v=vs.90).aspx, – BLUEPIXY Jan 29 '14 at 15:04

3 Answers3

41

It is a function that belongs specifically to the Microsoft compiler.

scanf originally just reads whatever console input you type and assign it to a type of variable.

If you have an array called first_name[5] and you use scanf for "Alex", there is no problem. If you have the same array and assign "Alexander", you can see it exceeds the 5 slots that the array contains, so C will still write it on memory that doesn't belong to the array and it might or might not crash the program, depending if something tries to access and write on that memory slot that doesn't belongs to first_name. This is where scanf_s comes in.

scanf_s has an argument(parameter) where you can specify the buffer size and actually control the limit of the input so you don't crash the whole building.

Andreas Fester
  • 36,091
  • 7
  • 95
  • 123
0xFED5550
  • 586
  • 6
  • 9
  • 8
    "where you can specify the buffer size" -> that is wrong. Correct: "where you can specify the buffer size and you must specify it for all input parameters of type c, C, s, S, or [." Therefore, simply adding postfix "_s" to programs that used scanf("...%s...", ...) leads to a program, which compiles with NO WARNING, but DOES NOTHING, since 0-size buffer is assumed and no data are read in. – Palo Dec 21 '15 at 21:28
  • 1
    Actually, in Visual Studio, the compiler complians whenever `%s` or `%c` is used without a buffer length argument. – Anders Marzi Tornblad Jun 17 '16 at 12:08
  • 2
    The `_s` functions are now part of C11 and portable. – Dai Oct 30 '16 at 03:32
  • 4
    *The `_s` functions are now part of C11 and portable.* Annex K is optional, and the Microsoft implementation is not portable. [**Field Experience With Annex K — Bounds Checking Interfaces**](http://www.open-std.org/jtc1/sc22/WG14/www/docs/n1967.htm#impementations): "Microsoft Visual Studio implements an early version of the APIs. However, the implementation is incomplete and conforms neither to C11 nor to the original TR 24731-1. ... As a result of the numerous deviations from the specification the Microsoft implementation cannot be considered conforming or portable." – Andrew Henle Feb 22 '19 at 16:49
12

scanf_s() is not described by the C99 Standard (or previous ones).

If you want to use a compiler that targets C99 (or previous) use scanf().

For C11 Standard (and eventually later ones) scanf_s() is much harder to use than scanf() for improved security against buffer overflows.

C11 fscanf_s(): http://port70.net/~nsz/c/c11/n1570.html#K.3.5.3.2

~~~~~~~~~~~~~~~~

If you have a C99 compiler with extras that provides scanf_s() as an extension and don't mind losing portability, check your compiler documentation.

pmg
  • 106,608
  • 13
  • 126
  • 198
  • 3
    Note that Annex K of the C11 Standard is optional. An implementation can claim to be C11 and not provide `scanf_s()` (you can check with `#if defined(__STDC_LIB_EXT1__)`). – pmg Feb 14 '16 at 17:43
  • 3
    I would not call it "much harder" to use. It's simply a matter of providing buffer sizes whenever scanning for strings och characters, which you should already be doing anyway! – Anders Marzi Tornblad Jun 17 '16 at 12:07
0

What you can do to avoid this error is to paste the thing between the <>: <_CRT_SECURE_NO_WARNINGS> to a place. To get to the place right click on your project in the solution explorer and click on the properties. then go to the configuration properties, then the c/c++, then the preprocessor. then in preprocessor definitions, after everything, add a semicolon and paste the thing in. then press apply and ok. Your problem should be solved.