有没有办法为 fscanf 实现包装函数?

Is there a way to implement a wrapper function for fscanf?

我试图为所有文件操作编写一个包装函数。但是我无法为 fscanf 实现包装函数。我自己的函数是这样的:

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

您需要使用 vfscanf。参见 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;
}

除了需要 va_listvfscanf 之外,您还可以使用可变参数模板:

template <typename ... Ts>
int scan(const char* format, Ts&&... args)
{
    int result = ::fscanf(_ptr, format, std::forward<Ts>(args)...);
    return result;
}

对于必须使用比 C++11 更旧的标准的用户,您可以实现自己的 vfscanf 函数,如下所示:

 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;
}

进一步information