C ++宏中正确的字符串/ char转换

时间:2017-10-27 19:30:16

标签: c++ macros char stdstring

我继承了一些导致大量编译器警告的代码,并且不是一个足够强大的C ++程序员来弄清楚如何正确地解决它。即:

log.h:

On Error Resume Next
RutaArchivo = Application.GetOpenFilename(Title:="Test", _
                        filefilter:="Excel files (*.xlsx), *.xlsx")
Workbooks.Open Filename:=RutaArchivo
With Application

.ScreenUpdating = False
.EnableEvents = False
.DisplayAlerts = False
End With

End Sub

log.cpp

#include <stdarg.h>
#include <libgen.h>
#include <errno.h>
#include <string.h>

void log(const char* fmt, ...) __attribute__((format (printf, 1, 2)));
#define error(fmt, ...) ow_log("ERROR[%s:%s()@%d]: " fmt, basename(__FILE__), __func__, __LINE__, ##__VA_ARGS__)
#define sys_error(fmt, ...) ow_log("ERROR[%s:%s()@%d]: System error: %s:" fmt, basename(__FILE__), __func__, __LINE__, strerror(errno), ##__VA_ARGS__)

使用示例:

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

void log(const char* fmt, ...)
{
    time_t t = time(NULL);
    struct tm tm = *localtime(&t);

    printf("%04d-%02d-%02d %02d:%02d:%02d ", tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec);
    va_list args;
    va_start(args, fmt);
    vprintf(fmt, args);
    printf("\n");
    fflush(stdout);
    va_end(args);
}

C ++程序员可能会立即看到它,但我无法做到。无论何时使用,我得到的是:

int args = 6;
log("Some string not explicitly typed with %i interpolated arguments", args);
error("Something went wrong here");

看起来代码已经有一段时间了,并且我没有看到任何非常糟糕的不良影响,但这使得阅读编译器输出相当困难(并且似乎实际上错了),所以我试着解决它。我尝试了一些不同的投射策略,但似乎没有任何效果,我认为我误解了宏是如何工作的以及它使用的所有内置函数。

1 个答案:

答案 0 :(得分:2)

根据this page,basename()的原型是

char *basename(char *path); 

并且文档说:

  

basename()函数可以修改path指向的字符串,并且可以返回指向静态存储的指针,然后可以通过对basename()的后续调用来覆盖该指针。

因此,您不应将字符串文字传递给此函数。

您应该使用的功能是

char * basename_r(const char *path, char *bname);

其中bname是要使用的函数的临时存储空间。