0

I was trying to write a wrapper function for all file operations. But I couldn't manage to implement wrapper function for fscanf. My own function is like this:

scan(const char * _Format, ... )
{
    va_list args;
    va_start(args, _Format);
    int result = ::fscanf(_ptr, _Format, args);
    va_end(args);
    return result;
}

3 Answers3

4

You need to use vfscanf. See more on vfscanf.

int scan(const char * _Format, ... )
{
    va_list args;
    va_start(args, _Format);
    int result = ::vfscanf(_ptr, _Format, args);
    va_end(args);
    return result;
}
R Sahu
  • 204,454
  • 14
  • 159
  • 270
  • Thank you for your help. But I couldn't manage to work vfscanf out in visual studio. It seems there is no vfscanf function in it. – Aykut Burak SAFAK Aug 10 '15 at 07:23
  • @AykutBurakSAFAK, you have accepted my answer. Does it mean that you were able to get it to work? – R Sahu Aug 10 '15 at 14:59
  • I wasn't able to get it work on my own project but this solutions works on the systems that uses C++11 standard so your answer solves the problem mine is an exceptional situation. – Aykut Burak SAFAK Aug 10 '15 at 15:31
3

Alternatively to the use to vfscanf which takes a va_list, you may use variadic template:

template <typename ... Ts>
int scan(const char* format, Ts&&... args)
{
    int result = ::fscanf(_ptr, format, std::forward<Ts>(args)...);
    return result;
}
Jarod42
  • 203,559
  • 14
  • 181
  • 302
  • Thank you for your help but it seems I have to use an older c++ standard than the c++11 so I'm not able to use variadic templates or vfscanf which is so annoying. – Aykut Burak SAFAK Aug 10 '15 at 08:50
0

For the ones who have to use an older standard than C++11 you can implement your own vfscanf function like the following:

 int vfscanf(FILE* file, const char *format, va_list argPtr)
{
    size_t count = 0;
    const char* p = format;

    while(1)
    {
        char c = *(p++);
        if (c == 0) 
            break;

        if (c == '%' && (p[0] != '*' && p[0] != '%')) 
            ++count;
    }

    if (count <= 0)
        return 0;

    int result;

    _asm
    {
        mov esi, esp;
    }

    for (int i = count - 1; i >= 0; --i)
    {
        _asm
        {
            mov eax, dword ptr[i];
            mov ecx, dword ptr [argPtr];
            mov edx, dword ptr [ecx+eax*4];
            push edx;
        }
    }

    int stackAdvance = (2 + count) * 4;

    _asm
    {
        mov eax, dword ptr [format];
        push eax;
        mov eax, dword ptr [file];
        push eax;

        call dword ptr [fscanf];

        mov result, eax;
        mov eax, dword ptr[stackAdvance];
        add esp, eax;
    }

    return result;
}

For further information.