Search code examples
arrayscscanf

What's the correct way to use scanf_s in using string arrays?


char array1[10];
scanf_s("%9s", array1, (unsigned)_countof(array1);

What's mean of (unsigned)_countof(array1)?

and what's different from use scanf_s("%9s", array1, sizeof(array1);?

both worked, but I want to understand about it more surely


Solution

  • What's the correct way to use scanf_s in using string arrays?

    scanf_s() with "%9s" is not for string arrays. It is for reading text and saving as a single string, which is a character array with a null character.

    Its proper use is complicated by MSVC expects a different type in the count argument than C11. In C11 and later, scanf_s() is an optional function of the standard library and lacks wide acceptance.

    // MSVC - type unsigned expected, hence the cast.
    scanf_s("%9s", array1, (unsigned)_countof(array1);
    
    // C11 - type size_t expected
    scanf_s("%9s", array1, sizeof array1 / sizeof array1[0]);
    

    Proper use of either obliges code to check the return value of scanf_s()

    if (1 == scanf_s("%9s", ...)) Success();
    else Fail();
    

    What's mean of (unsigned)_countof(array1)?

    _countof() is an MSVC macro equivalent to (sizeof(array) / sizeof(array[0])). When passed an array, it returns the count of elements in the array as type size_t. Casting to unsigned gets the expected type as with MSVC scanf_s(). The value may truncate due to the cast - a rare issue with huge arrays.


    what's different from use scanf_s("%9s", array1, sizeof(array1));?

    The expected type of sizeof(array1) is size_t and not unsigned as expected in MSVC - leading to undefined behavior. When size_t is as unsigned, that is OK, else a real problem.

    The conceptual value is wrong. It should be the array element count, not the byte size of the array. Either OK here as sizeof(char)==1, yet wrong if code moved to say using wide characters.


    both worked

    Code is not portable. It may have "worked" in OP's case, but lacks portability.


    Consider alternatives to scanf_s(), scanf() like fgets().