簡體   English   中英

我正在C / Linux中實現printf功能

[英]I'm implementing printf function in C/Linux

程序:

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

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

 #endif

這是我的函數的Header文件。

#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來顯示一個角色。

當我做my_print("%c", 'd'); main.c它編譯並顯示d

但是當我做my_print("%c", "hi"); ,它仍然編譯並顯示一個數字。

題:

寫入之后(或之前) a = va_arg(print, char); 有沒有辦法檢查我的輸入是否是不同的數據類型? 如果我的輸入是不同的數據類型,我正在嘗試顯示錯誤。

我在這個問題上待了2天,但找不到任何答案。 非常感謝您的參與!

當我做my_print("%c", "hi"); ,它仍然編譯並顯示一個數字

你有一些未定義的行為 ,所以要害怕 你的my_printf會使用錯誤類型的參數調用va_arg (期望的char被提升為int ,得到char* )。

為了解釋發生的情況,您應該深入了解實現細節(查看匯編代碼,例如使用gcc -Wall -fverbose-asm -O -S ;研究處理器 ,其指令集架構應用程序二進制接口調用約定 )。 你不想這樣做 ,可能需要數年而且不可重復。

立即閱讀UB上Lattner的博客

然后下載C11規范n1570 ....

你也可以使用gcc使用一些函數屬性 不要忘記編譯所有警告和調試信息( gcc -Wall -Wextra -g

寫完a = va_arg(print, char); 有沒有辦法檢查我的輸入是否是不同的數據類型?

不,不是真的,也不是永遠。 format函數屬性可能會有所幫助。 你也可以花幾個月的時間用自己的插件或一些GCC MELT擴展來定制GCC(這不值得你花時間)。 注意停機問題賴斯定理 (每個都使靜態源代碼程序分析如此具有挑戰性)。 另請參閱Frama-C等源分析工具。

我正在實現printf功能

BTW研究C標准庫 (如GNU glibcmusl-libc )現有自由軟件實現的源代碼可能是鼓舞人心的; 它們基於系統調用(2)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM