【问题标题】:Hexidecimal not printing properly in homemade printf() function在自制的 printf() 函数中无法正确打印十六进制
【发布时间】:2016-10-20 23:37:53
【问题描述】:

我正在编写一个操作系统,但在创建 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);
}

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

【问题讨论】:

    标签: c string operating-system printf standard-library


    【解决方案1】:

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

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

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

    【讨论】:

    • 就在我之前:const string str2 没有分配内存。
    • 谢谢!我弄清楚了主要思想;但是你弄错了一些细节(例如 sizeof(buf2) 对基础来说不是一个好主意。)我正在对其进行一些编辑,使其符合我发现的工作,然后我会接受它。
    猜你喜欢
    • 1970-01-01
    • 2015-02-14
    • 1970-01-01
    • 2023-02-09
    • 2015-06-13
    • 2013-02-18
    • 2014-09-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多