在不使用 stdarg.h 库的情况下在 C 中创建一个简单的 printf 函数

问题描述 投票:0回答:3

我一直致力于用 c 编写一个非常简单的 printf 函数,它执行以下操作:它打印字符串、有符号整数、无符号整数和 % 符号。我检查过的每个实现都使用 stdarg.h 库。但是,我正在尝试不这样做。问题是我不确定如何在 printf 中实现可变数量的参数。到目前为止,我想出的唯一方法是对参数使用指针并尝试递增它们。这种方法似乎不起作用。

这是我到目前为止的代码:

#include <stdio.h>

void print_int(int n) {
    if (n < 0) {
        putchar('-');
        n = -n;
    }
    if (n / 10)
        print_int(n / 10);
    putchar(n % 10 + '0');
}

void print_uint(unsigned int n) {
    if (n / 10)
        print_uint(n / 10);
    putchar(n % 10 + '0');
}

void print_string(char *s) {
    while (*s)
        putchar(*s++);
}

void my_printf(char *format, ...) {
    void **arg = (void **) &format + 1;

    for (char *p = format; *p; p++) {
        if (*p != '%') {
            putchar(*p);
            continue;
        }

        switch (*++p) {
            case 'd':
                print_int(*(int *) arg++);
                break;
            case 'u':
                print_uint(*(unsigned int *) arg++);
                break;
            case 's':
                print_string(*(char **) arg++);
                break;
            case '%':
                putchar('%');
                break;
            default:
                putchar(*p);
                break;
        }
    }
}

int main() {
    int x = 42;
    unsigned int y = 1234567890;
    char *s = "Hello, world!";

    my_printf("Testing my_printf:\n");
    my_printf("Signed integer: %d\n", x);
    my_printf("Unsigned integer: %u\n", y);
    my_printf("String: %s\n", s);
    my_printf("Percent sign: %%\n");

    return 0;
}

我运行它得到的输出是:

Testing my_printf:
Signed integer: 849754744
Unsigned integer: 849754744
String: Y�Ź�U
Percent sign: %```


How can I fix this?
c pointers printf
3个回答
0
投票

如何读取传递给函数的可变参数的细节是高度特定于实现的。

使用可变参数正确实现函数的唯一方法是 通过

stdargs.h
.

中定义的函数

0
投票

因为我不能发表评论:/我会在这里分享我的想法。

对我来说,代码有效,所以这可能与编译器有关。我使用 Dev-C++ 和默认编译器,即 tdm-gcc 4.9.2 64 位。

也可能是您没有声明正确的编译器标志?我已经放了旗帜

-std=c11
.


0
投票

在 C 中访问可变数量参数的方式是通过

<stdarg.h>
.

如果你不愿意使用

<stdarg.h>

  • 再想想;
  • 再次反思;
  • 不断反思,直到你理智;
  • 如果您的课程作业要求您不使用
    <stdarg.h>
    ,请说出来;
  • 你即将踏上一个痛苦的世界,你的解决方案将绑定到你开发代码的特定平台,至少在你将它移植到所有其他 ABI(应用程序二进制接口)之前是这样。

除非你不能说服你的导师,否则不要这样做。如果你必须这样做,请使用平行但不同的名称(用于标题和其中定义的类型、宏和函数)对

<stdarg.h>
进行最小的重新实现。

© www.soinside.com 2019 - 2024. All rights reserved.