fopen、fprintf、fclose 的一行代码?
One-liner for fopen, fprintf, fclose?
我正在将一些非常临时的调试打印放入各种用户空间程序中,以找出在嵌入式 Linux 设备上运行的代码,我希望这些打印可以写入文件而不会使其保持打开状态。为了使调试在各种程序之间更具可移植性,最好有一个可以打开文件、写入文件和关闭文件而无需在其他地方定义 function/macro 的单行程序。我可以做类似的事情:
{ FILE *f = fopen("filename", "a"); if (f) { fprintf(f, "DEBUG MSG\n"); fclose(f); } else printf("File open error!\n"); }
这只是从以下位置删除空格:
{
FILE *f = fopen("filename", "a");
if (f) {
fprintf(f, "DEBUG MSG\n");
fclose(f);
}
else
printf("File open error!\n");
}
但这感觉不必要地复杂。有没有更简单的方法来做到这一点?同样,我不是在谈论使它成为一个函数,因为我希望它在不同的程序之间 copy/pasted 而不是每次都定义一个函数。它基本上只是用户空间的临时 printk 等价物。
Functions.
我的最短答案需要额外的字符。
fprintf(f, "DEBUG MSG\n");
的潜在问题
我假设 "DEBUG MSG\n"
是真实消息的一些占位符。如果真实消息包含 '%'
,则该函数将查找丢失的参数。使用 fputs()
- 它在 CPU 上也比 fprintf()
.
更轻
fputs(debug_message, f);
真正的消息可能缺少 '\n'
,然后在程序崩溃之前卡在缓冲中。完成后最好冲洗。
fputs(debug_message, f);
fflush(f);
迂腐:调试是为了解决问题。消息本身往往是 questionable/corrupt。考虑使用保护。 (我不相信过长的调试消息)。当然 fprintf()
中的垃圾越多,调试日志记录的性能影响就越大。
if (f) {
if (debug_message) {
fprintf(f, "%.99s", debug_message);
fflush(f);
fclose(f);
}
}
如 所述,将诊断消息发送至 stderr
,而不是 stdout
。
总的来说,我会使用包含在条件宏中的函数调用,而不是嵌入式代码。 YMMV.
#ifdef NDEBUG
#define DEBUG_PUTS(level, s)
#else
#define DEBUG_PUTS(level, s) debug_puts((level), __FILE__, __LINE__, (s))
#endif
如 Mark Plotnick 所述,Linux 系统的解决方法是:
system("echo DEBUG MSG >> filename");
它不漂亮但很快,copy/pasteable,并且在这种情况下易于使用,因为它还可以写入 /dev/kmsg
:
system("echo DEBUG MSG >> /dev/kmsg");
这允许它像 printk 一样工作。当然,这不是一个安全的解决方案,不能与任何干扰 bash 回显的字符一起使用,但对于临时静态调试消息,它工作正常。
我正在将一些非常临时的调试打印放入各种用户空间程序中,以找出在嵌入式 Linux 设备上运行的代码,我希望这些打印可以写入文件而不会使其保持打开状态。为了使调试在各种程序之间更具可移植性,最好有一个可以打开文件、写入文件和关闭文件而无需在其他地方定义 function/macro 的单行程序。我可以做类似的事情:
{ FILE *f = fopen("filename", "a"); if (f) { fprintf(f, "DEBUG MSG\n"); fclose(f); } else printf("File open error!\n"); }
这只是从以下位置删除空格:
{
FILE *f = fopen("filename", "a");
if (f) {
fprintf(f, "DEBUG MSG\n");
fclose(f);
}
else
printf("File open error!\n");
}
但这感觉不必要地复杂。有没有更简单的方法来做到这一点?同样,我不是在谈论使它成为一个函数,因为我希望它在不同的程序之间 copy/pasted 而不是每次都定义一个函数。它基本上只是用户空间的临时 printk 等价物。
Functions.
我的最短答案需要额外的字符。
fprintf(f, "DEBUG MSG\n");
我假设 "DEBUG MSG\n"
是真实消息的一些占位符。如果真实消息包含 '%'
,则该函数将查找丢失的参数。使用 fputs()
- 它在 CPU 上也比 fprintf()
.
fputs(debug_message, f);
真正的消息可能缺少 '\n'
,然后在程序崩溃之前卡在缓冲中。完成后最好冲洗。
fputs(debug_message, f);
fflush(f);
迂腐:调试是为了解决问题。消息本身往往是 questionable/corrupt。考虑使用保护。 (我不相信过长的调试消息)。当然 fprintf()
中的垃圾越多,调试日志记录的性能影响就越大。
if (f) {
if (debug_message) {
fprintf(f, "%.99s", debug_message);
fflush(f);
fclose(f);
}
}
如 stderr
,而不是 stdout
。
总的来说,我会使用包含在条件宏中的函数调用,而不是嵌入式代码。 YMMV.
#ifdef NDEBUG
#define DEBUG_PUTS(level, s)
#else
#define DEBUG_PUTS(level, s) debug_puts((level), __FILE__, __LINE__, (s))
#endif
如 Mark Plotnick 所述,Linux 系统的解决方法是:
system("echo DEBUG MSG >> filename");
它不漂亮但很快,copy/pasteable,并且在这种情况下易于使用,因为它还可以写入 /dev/kmsg
:
system("echo DEBUG MSG >> /dev/kmsg");
这允许它像 printk 一样工作。当然,这不是一个安全的解决方案,不能与任何干扰 bash 回显的字符一起使用,但对于临时静态调试消息,它工作正常。