在 C 中使用 printf() 重新实现 printf()

Lin*_*oln 5 c linux gcc variadic-functions embedded-linux

我正在制作一个嵌入式Linux项目,我想做一个简单的调试消息库,当我的代码处于生产阶段时,我可以在其中禁用调试消息(使用预编译指令)并替换数据库中某种类型的日志(将来)。我在重新实现时遇到了麻烦,printf()因为va_list. 到目前为止,这是我的代码:

\n

我的源文件:

\n
#include "debug_msgs.h"\n\n#define ENABLE_DEBUG_MSGS   1U\n\n#if ENABLE_DEBUG_MSGS\n\nint print(const char *fmt, ...) {\n    int n = -1;\n    va_list ap;\n    va_start(ap, fmt);\n    n = printf(fmt, ap);\n    va_end(ap);\n    return n;\n}\n\n#else\n\nint print(const char *fmt, ...) {\n    return 0;\n}\n\n#endif\n
Run Code Online (Sandbox Code Playgroud)\n

我的头文件:

\n
#ifndef DEBUG_MSGS_H\n#define DEBUG_MSGS_H\n\n#include <stdio.h>\n#include <stdlib.h>\n#include <string.h>\n#include <stdarg.h>\n#include <stdint.h>\n#include <unistd.h>\n\nint print(const char *fmt, ...);\n\n#endif\n
Run Code Online (Sandbox Code Playgroud)\n

我的问题是:\n我的实现可以编译(我知道这并不意味着什么),但是当我做一个简单的测试时,例如:

\n
int num1 = 10;\nint num2 = 100;\nint num3 = 1000;\nfloat floating = 3.14;\nchar str[] = {"Please work, please"};\nint number=-1;\nnumber = print("\\nTesting %d %d %d %f %s\\n", num1, num2, num3, floating, str);\nprintf("\\nnumber = %d\\n",number); //Just to check the return\n
Run Code Online (Sandbox Code Playgroud)\n

我得到这个输出:

\n
Testing -1095005212 100 -1095005212 -0.000002 H*\xef\xbf\xbd \n\nnumber = 52\n
Run Code Online (Sandbox Code Playgroud)\n

补充信息:

\n

这是我的平台信息:\nLinux mdm9607 3.18.44 #1 PREEMPT Tue Sep 13 19:45:33 UTC 2022 armv7l GNU/Linux

\n

我的编译器信息:\narm-oe-linux-gnueabi-gcc

\n

我的 $CFLAGS:\n -O2 -fexpensive-optimizations -frename-registers -fomit-frame-pointer -MMD -MP

\n

我的 $LDFLAGS:

\n

-Wl,-O1 -Wl,--hash-style=gnu -Wl,--as-needed

\n
LDFLAGS += -lumdp -lumdpcommon\nLDFLAGS += -lpthread -lxml2 -lrt\nLDFLAGS += -lm\n
Run Code Online (Sandbox Code Playgroud)\n

chq*_*lie 10

printf您应该使用vprintfor来代替,vfprintf并带有va_list参数:

#include <stdarg.h>
#include <stdio.h>

int print(const char *fmt, ...) {
    int n;
    va_list ap;
    va_start(ap, fmt);
    n = vprintf(fmt, ap);
    va_end(ap);
    return n;
}
Run Code Online (Sandbox Code Playgroud)

编译错误代码是因为printf,作为可变参数函数,可以接受格式字符串之后的任何参数类型。然而,您可以printf通过启用更多编译器警告来避免参数的类型不匹配:gcc -Wall -Wextra -Werror至少会抱怨使用printf非常量格式字符串,并且如果格式字符串是字符串文字,则会执行编译时类型检查。