十六进制无法在自制的 printf() 函数中正确打印

Hexidecimal not printing properly in homemade printf() function

我正在编写 OS,但在制作 printf() 函数时遇到了问题。

当通过已确定有 % 的 switch 语句并试图找出下一个字符是什么时,会发生这种情况:

print(string str) 将字符串 str 打印到 stdout(但没有 %x、%d、%s 等)。

itoa(int n, string str, const uint8_t base) 将 int 转换为指定基数的字符串。

case 'i':
case 'd': {     // interger
    const string str =
        itoa(
        va_arg(args, int),
        str, 10);
    print(str);
    i++;
    break;
}

case 'X':
case 'x': {     // hexidecimal
    const string str2 =
        itoa(
        va_arg(args, int),
        str2, 16);
    print("0x");
    print(str2);
    i++;
    break;
}

%d 和 %i 完全按照它应该做的,但是如果由于某种原因输入小于 16,%x 就不能正常工作。但奇怪的是 如果我注释掉处理 %d 和 %i 的部分,%x 会起作用。 我不知道为什么会这样。我试过切换 d 和 x 的作用等等,但没有任何效果。我还尝试确保所有其他功能都正常工作,而且它们都正常工作。

如果有人想查看完整代码,请看这里:

strLen(string str) 求字符串 str.

的长度

printch(char c) 打印字符 c .

void printf (const string format, ... )
{
    const size_t length = strLen(format);
    va_list args;
    va_start (args, format);

    // print every character in string
    for (size_t i=0; i < length; i++)
    {
        // percent signals special functionality
        if (format[i] == '%')
        {
            switch (format[i+1])
            {
                case '%':       // "%%" = %
                    printch('%');
                    break;

                case 'i':
                case 'd': {     // interger
                    const string str =
                        itoa(
                        va_arg(args, int),
                        str, 10);
                    print(str);
                    i++;
                    break;
                }

                case 'x': {     // hexidecimal
                    const string str2 =
                        itoa(
                        va_arg(args, int),
                        str2, 16);
                    print("0x");
                    print(str2);
                    i++;
                    break;
                }

                case 'c':       // character
                    printch(
                    va_arg(args, char));
                    i++;
                    break;

                case 's':       // string
                    print(
                    va_arg(args, string));
                    i++;
                    break;

                default:
                    i++;
                    break;
            }
        }
        else printch(format[i]);
    }

    va_end (args);
}

有谁知道这里发生了什么以及如何解决它?请帮忙!

当注释掉不相关的代码使代码有问题时 "work",您可以确定您正在查看未定义的行为。你的代码并没有真正 "work";它不会导致出现在输出中的错误。

在您的情况下,问题似乎与您传递给 itoa 的缓冲区有关:您正在向它传递一个空字符串,而不是传递一个缓冲区。您应该将一个小缓冲区传递给 itoa,然后才从中构造一个字符串,如下所示:

char buf2[17];
itoa(va_arg(args, int), buf2, sizeof(buf2));
const string str2(buf2, sizeof(buf2));