在没有va_list的情况下实现printf

时间:2017-04-13 18:52:59

标签: c

在最后的编程作业中,我们应该在不使用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没有像我预期的那样打印出来。知道代码有什么问题吗?谢谢!

2 个答案:

答案 0 :(得分:0)

总结几个人所提到的:

printf采用可变长度参数列表。要访问这些参数,您需要了解参数如何传递给函数的机制。 C规范强调要避免声明像这样的低级别的东西应该如何工作;它会因平台而异。相反,C标准规定所有这些特定于平台的东西都要包含在标准化界面后面,并称之为stdarg.h

这意味着这里有两种可能的结果。您的教师要么您希望得出结论,它不能在标准C中完成,并且对{0}}存在的原因有更深入的了解,或者他们希望您做一些非常特定于平台的事情。如果是后者,那么这不是问题(您将调用大量未定义的行为并在语言规范之外方式),这是关于您的平台的问题& #39;低级接口。在我们为您提供帮助之前,您需要详细了解您的处理器架构和ABI版本。

答案 1 :(得分:0)

即使您确定参数将在堆栈中,没有对齐且堆栈具有正确的方向,您的代码也会出现问题。

  1. C具有值语义调用。即,对于intchar,值本身位于堆栈,而不是指针。因此,格式字母'd'和'c'的情况下traverse的增量不正确。
  2. 如果是'd',则获取整数参数并将其解释为char。但是,您必须将其转换为字符串并输出字符串的字符。