c - 我在 C/Linux 中实现 printf 函数

标签 c linux printf

程序:

 #ifndef PRINTF_H
 #define PRINTF_H
 #include "my_put_char.h"

 int my_printf(char *str, ...);

 #endif

这是我的函数的头文件。

#include <stdio.h>
#include "my_put_char.h"

void my_put_char(char c) 
{
     fwrite(&c, sizeof(char), 1, stdout);
}

这是我的 putchar 实现 (my_put_char.c)。

#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include "printf.h"

int my_printf(char *str, ...)
{   
    if(str == NULL)
        return 0;

    int i;
    char a;

    va_list print;
    va_start(print,str);

    for(i = 0; str[i] ; i++)
    {
        if(str[i] == '%')
        {
            i++;
            switch(str[i])
            {
                case 'c':
                a = va_arg(print, char);
                my_put_char(a);
                break;
            }
        }
     }
     va_end(print);
     return 0;
}

最后,这是我的 printf 实现的一部分。 我正在测试 %c 来显示一个字符。

当我从 main.c 执行 my_print("%c", 'd'); 时 它编译并显示 d

但是当我执行 my_print("%c", "hi"); 时,它仍然会编译并显示一个数字。

问题:

在(或之前)写 a = va_arg(print, char); 有没有办法检查我的输入是否是不同的数据类型? 如果我的输入是不同的数据类型,我会尝试显示错误。

我在这个问题上研究了 2 天,但找不到任何答案。 非常感谢您的宝贵时间!

最佳答案

when I do my_print("%c", "hi"); , it still compiles and displays a number

你有一些 undefined behavior ,所以是 scared 。您的 my_printf 将使用错误类型的参数调用 va_arg(应将 char 提升为 int,得到 char*).

要解释正在发生的事情,您应该深入研究实现细节(查看汇编代码,例如使用 gcc -Wall -fverbose-asm -O -S;研究您的 processor ,它的 instruction set architecture ,它的application binary interfacecalling conventions)。 你不想那样做,这可能需要数年时间并且不可重现。

绝对读取 Lattner's blog on UB ,现在!

然后下载C11规范n1570 ....

您还可以使用 gcc,使用一些 function attributes 。不要忘记使用所有警告和调试信息进行编译 (gcc -Wall -Wextra -g)

after writing a = va_arg(print, char); Is there a way to check whether my input is a different data type?

不,不是真的,也不总是。但是 format 函数属性可以提供帮助。你也可以花几个月的时间用你自己的 plugin 或一些 GCC MELT 扩展来定制 GCC(这不值得你花时间)。请注意 Halting ProblemRice's Theorem(每个都使 static 源代码 program analysis 如此具有挑战性)。另请查看源代码分析工具,例如 Frama-C

I'm implementing printf function

顺便说一句,研究 free software 的现有 C standard library 实现的源代码(例如 GNU glibcmusl-libc )可能会鼓舞人心;它们基于 syscalls(2)

关于c - 我在 C/Linux 中实现 printf 函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46458591/

相关文章:

c - 延迟之前的 printf 在 C 中不起作用

c - strdup() : Confused about warnings ('implicit declaration' , 'makes pointer...without a cast' 内存泄漏)

c - 递归搜索和插入二叉树

c - 如何将 char 'a' 设置为 char 指针数组?

php - 无法连接到本地套接字,连接被拒绝

c++ - 为什么在包含 iostream 时可以使用 printf()?

c - 链表无法正确循环

linux - 从私钥生成公共(public) ssh key

linux - 在 12.04 LTS 系统上安装 LAMP 后,当我尝试打开文件时,phpMyAdmin 下载文件

c - 数组C编程中打印出奇怪的字母