十字形不能在自制printf()函数中正确打印

时间:2016-06-19 18:04:32

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

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

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

1 个答案:

答案 0 :(得分:1)

当评论出不相关的代码使得代码有问题&#34;工作&#34;时,您可以确定您正在查看未定义的行为。你的代码并没有真正&#34;工作&#34 ;;它不会导致在输出中出现错误。

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

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