1

If I didn't have access to the internet, but knew that I wanted to use the scanf_s() function to take input from the keyboard (stdin), how would I know where to declare the buffer?

At the moment, when I step into the scanf_s() function in Visual Studio, I see this:

#if __STDC_WANT_SECURE_LIB__

    _Check_return_opt_
    _CRT_STDIO_INLINE int __CRTDECL scanf_s(
        _In_z_ _Scanf_s_format_string_ char const* const _Format,
        ...)
#if defined _NO_CRT_STDIO_INLINE // SCANF
    ;

So, I can see that scanf_s() takes 1 defined argument (char const * _Format) which, in this case, could be some placeholder such as be "%s", but nothing for the second argument - the memory address of the buffer to store the result of the scanning.

Deduplicator
  • 44,692
  • 7
  • 66
  • 118
sharkbites
  • 101
  • 1
  • 8
  • It is not you who defines the buffer that takes the input; that is the OS. You define the buffer that receives the result of the scanning. – Paul Ogilvie Jun 27 '18 at 11:40
  • Sorry, thats what I mean. – sharkbites Jun 27 '18 at 11:42
  • No need to be sorry; hope this explanation answers your question. – Paul Ogilvie Jun 27 '18 at 11:43
  • 2
    The important part is called a variable argument list indicated by `...` after the last specified parameter. – Gerhardh Jun 27 '18 at 11:45
  • if you "didn't have access to the internet", you'd have bigger problems than trying to remember function prototypes :-) – paxdiablo Jun 27 '18 at 11:48
  • @Gerhardh , I understand that, but it seems awfully vague to have that in your arguments, right? If scanf was declared `scanf(char const * const _Format , char * buffer)` , I think that would be a better indicator that scanf() accepted a buffer than leaving it out altogether – sharkbites Jun 27 '18 at 12:09
  • 1
    If `scanf` was declared that way it would not be able to scan more values or different values than exactly one single string. It would be a completely different function than what it is now. – Gerhardh Jun 27 '18 at 13:13
  • @sharkbites `scanf(char const * const _Format , char * buffer)` would make usages like `int x; scanf("%d", &x)` a type mis-match. – chux - Reinstate Monica Jun 27 '18 at 14:13

1 Answers1

1

scanf_s takes a variable list of arguments. The first argument is mandatory, a string with the conversion specifications, the following arguments depend on what conversion specifications are present in the format string.

For each conversion specification %s, %c and %[, scanf_s expects 2 arguments for the conversion: a pointer to char (char *) and a number passed with type rsize_t that specifies the size of the array pointed to by the char * argument.

Here is an example:

#define __STDC_WANT_LIB_EXT1__ 1 
#include <stdio.h>

int main() {
    char buf[32];
    int res;

    printf("Type a word: ");
    res = scanf_s("%s", buf, sizeof(buf));
    switch (res) {
    case EOF:
        printf("Input failure\n");
        break;
    case 0:
        printf("Matching failure\n");
        break;
    case 1:
        printf("Success: you typed '%s'\n", buf);
        break;
    default:
        printf("Unexpected return value %d\n", res);
        break;
    }
    return 0;
}

Note however that support for scanf_s is far from universal. Microsoft platforms usually support it, but with varying semantics, while linux and Mac C libraries usually don't. Read this question to understand Why didn't gcc implement _s functions?

chqrlie
  • 131,814
  • 10
  • 121
  • 189