Best way to get around the lack of vwscanf in Visual C ++?

The C ++ 11 standard indicates that vwscanf is available through the <cwchar> header (and therefore <wchar.h> ). However, it seems to be missing in Visual C ++. With this function, I could write & hellip;

 inline int scanf( CodingValue const* format, ... ) { va_list args; va_start( args, format ); return ::vwscanf( format->ptr(), args ); } 

but without it, that is, with Visual C ++ 10.0, which also lacks support for C ++ 11 variable templates, I'm m shortened to writing & hellip;

 inline int scanf( CodingValue const* format, void* a01 = 0, void* a02 = 0, void* a03 = 0, void* a04 = 0, void* a05 = 0, void* a06 = 0, void* a07 = 0, void* a08 = 0, void* a09 = 0, void* a10 = 0, void* a11 = 0, void* a12 = 0 ) { int const nArgs = !!a01 + !!a02 + !!a03 + !!a04 + !!a05 + !!a06 + !!a07 + !!a08 + !!a09 + !!a10 + !!a11 + !!a12; BasicCodingValue const* const f = format->ptr(); switch( nArgs ) { case 0: return ::wscanf( f ); case 1: return ::wscanf( f,a01 ); case 2: return ::wscanf( f,a01,a02 ); case 3: return ::wscanf( f,a01,a02,a03 ); case 4: return ::wscanf( f,a01,a02,a03,a04 ); case 5: return ::wscanf( f,a01,a02,a03,a04,a05 ); case 6: return ::wscanf( f,a01,a02,a03,a04,a05,a06 ); case 7: return ::wscanf( f,a01,a02,a03,a04,a05,a06,a07 ); case 8: return ::wscanf( f,a01,a02,a03,a04,a05,a06,a07,a08 ); case 9: return ::wscanf( f,a01,a02,a03,a04,a05,a06,a07,a08,a09 ); case 10: return ::wscanf( f,a01,a02,a03,a04,a05,a06,a07,a08,a09,a10 ); case 11: return ::wscanf( f,a01,a02,a03,a04,a05,a06,a07,a08,a09,a10,a11 ); case 12: return ::wscanf( f,a01,a02,a03,a04,a05,a06,a07,a08,a09,a10,a11,a12 ); } } 

Or, I could make an assembly as I liked it 15 years ago when I ran into a similar (or perhaps the same) problem, but this is not entirely correct.

Can you suggest a better way?

+4
source share
3 answers

As I understand it, this is not an error for calling a variational function with additional arguments (that is, more than given) in C (and possibly in C ++, although I still have to find the final statement anyway).

The best I have received on the C ++ side so far: 5.2.2 [expr.call]:

You can declare a function to accept fewer arguments (by declaring default arguments (8.3.6)) or more arguments (using ellipsis, ... or a package of function parameters (8.3.5)) than the number of parameters in the function definition (8.4 )

18.10 [support.runtime] deviates to ISO C 4.8.1.1 regarding restrictions for va_start() .

I see nowhere where it says that "you should not pass unnecessary arguments," so it seems that it would be unreasonable to assume that this is not prohibited.

If this is not legal in C ++, to give additional arguments, you can use C ++ to handle the default arguments and call the C function when the default values ​​are "filled", so you only ever call one function C, no matter how many arguments were given.

So in C ++ you would do:

 extern "C" { int real_scanf( const char* format, void* a01, void* a02, void* a03, void* a04, void* a05, void* a06, void* a07, void* a08, void* a09, void* a10, void* a11, void* a12 ); } inline int scanf( CodingValue const* format, void* a01 = 0, void* a02 = 0, void* a03 = 0, void* a04 = 0, void* a05 = 0, void* a06 = 0, void* a07 = 0, void* a08 = 0, void* a09 = 0, void* a10 = 0, void* a11 = 0, void* a12 = 0 ) { BasicCodingValue const* const f = format->ptr(); return real_scanf( f,a01,a02,a03,a04,a05,a06,a07,a08,a09,a10,a11,a12 ); } 

and then in C you can do:

 int real_scanf( const char* format, void* a01, void* a02, void* a03, void* a04, void* a05, void* a06, void* a07, void* a08, void* a09, void* a10, void* a11, void* a12 ) { return wscanf( format,a01,a02,a03,a04,a05,a06,a07,a08,a09,a10,a11,a12 ); } 
+2
source

My awoodland version answer: default values ​​required:

 #include <cstdio> #include <cassert> template <typename CodingValue> int scanf(CodingValue const* format, void* a01 = 0, void* a02 = 0, void* a03 = 0, void* a04 = 0, void* a05 = 0, void* a06 = 0, void* a07 = 0, void* a08 = 0, void* a09 = 0, void* a10 = 0, void* a11 = 0, void* a12 = 0) { return wscanf( format,a01,a02,a03,a04,a05,a06,a07,a08,a09,a10,a11,a12 ); } int main() { int v(0); int rc = scanf<wchar_t>(L"%d", &v); assert(1 == rc); return 0; } 

Please refer to the Dennis Zickefoose comments above for some details.

+1
source

There is an implementation of int vwscanf(format, ...) with VS2010.

File = wscanf.c

Directory = C: \ Program Files (x86) \ Microsoft Visual Studio 10.0 \ VC \ crt \ src

0
source

Source: https://habr.com/ru/post/1379500/


All Articles