自己的printf功能不起作用

时间:2014-09-24 15:51:54

标签: c++ arguments variadic-functions

我试图用c ++编写我自己的printf func for practive但是我得到了以下运行时错误,我无法弄清楚原因:

Access violation reading location 0x33333333.

以下是代码:

void myPrintf(char* szStr, ...)
{
    va_list marker;
    va_start(marker, szStr);
    va_arg(marker, char*);
    char opCode;
    int nLen = istrlen(szStr);
    for (int i = 0; i < nLen; i++)
    {
        if (szStr[i] != '%')
            cout << szStr[i];
        else
        {
            if (i + 1 < nLen)
            {
                opCode = szStr[i + 1];
                switch (opCode)
                {
                case 'd':
                    cout << va_arg(marker, int);
                    i += 2;
                    break;
                case 'f':
                    cout << va_arg(marker, float);
                    i += 2;
                    break;
                case 's':
                    cout << va_arg(marker, char*);
                    i += 2;
                    break;
                default:
                    cout << '%';
                    break;
                }
            }
            else
                cout << '%';
        }
    }
    cout << endl;
}

我无法弄清楚为什么会这样, 有人可以告诉我,我做错了什么?

我使用以下代码调用该函数:

myPrintf("%d %s %f", 5, "test", 10.1);

当程序崩溃时,它显示我的代码:

static size_t __CLRCALL_OR_CDECL length(const _Elem *_First)
    {   // find length of null-terminated string
    return (*_First == 0 ? 0
        : _CSTD strlen(_First));
    }

1 个答案:

答案 0 :(得分:2)

va_arg(marker, char*);之后的第一个va_start(marker, szStr);应该被删除,因为它会在szStr之后使用参数(例如示例中的5)。 va_start宏正在消耗起始参数。

并且float参数始终作为double传递(同样short参数作为int传递,等等......)所以您的va_arg(marker, float);应该是一个va_arg(marker, double);