十六进制无法在自制的 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));
我正在编写 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));