在最后的编程作业中,我们应该在不使用va_list的情况下实现printf。我不能让我的工作。这是我的尝试:
#include<stdio.h>
#include<stdarg.h>
#include <string.h>
#include <stdlib.h>
int myprintf( const char * format, ... )
{
void *traverse = &format;
traverse += sizeof(char*);
int i,j;
char k;
char * str;
for (i = 0; i < strlen(format); i++)
{
if (format[i] == '%')
{
switch (format[i+1])
{
case 's':
str = *( (char**)traverse );
for (j = 0; j < strlen(str); j++)
{
k = str[j];
putchar(k);
}
traverse += sizeof(char*);
break;
case 'd':
j = *( (int*)traverse );
putchar(j);
traverse += sizeof(int*);
break;
case 'c':
k = *( (char*)traverse );
putchar(k);
traverse += sizeof(char*);
break;
case '%' :
putchar('%');
break;
}
i++;
}
else
{
putchar(format[i]);
}
}
}
int main()
{
char k = 'a';
int g = 6;
myprintf("Hello, this is %d How are You", 6);
}
输出结果是'你好,这就是你好吗&#39;并且int 6没有像我预期的那样打印出来。知道代码有什么问题吗?谢谢!
答案 0 :(得分:0)
总结几个人所提到的:
printf
采用可变长度参数列表。要访问这些参数,您需要了解参数如何传递给函数的机制。 C规范强调要避免声明像这样的低级别的东西应该如何工作;它会因平台而异。相反,C标准规定所有这些特定于平台的东西都要包含在标准化界面后面,并称之为stdarg.h
。
这意味着这里有两种可能的结果。您的教师要么您希望得出结论,它不能在标准C中完成,并且对{0}}存在的原因有更深入的了解,或者他们希望您做一些非常特定于平台的事情。如果是后者,那么这不是问题(您将调用大量未定义的行为并在语言规范之外方式),这是关于您的平台的问题& #39;低级接口。在我们为您提供帮助之前,您需要详细了解您的处理器架构和ABI版本。
答案 1 :(得分:0)
即使您确定参数将在堆栈中,没有对齐且堆栈具有正确的方向,您的代码也会出现问题。
int
和char
,值本身位于堆栈,而不是指针。因此,格式字母'd'和'c'的情况下traverse
的增量不正确。char
。但是,您必须将其转换为字符串并输出字符串的字符。