如何使用预处理器从源文件中获取一行文本

How to get line of text from source file using Preprocessor?

本文关键字:文本 一行 获取 预处理 何使用 处理器 源文件      更新时间:2023-10-16

我们有一个文件和一行(__file____line__),我们想打印它的内容。通过预处理器,这样的事情可能吗?

也许是这样的?

#include <stdio.h>
#define DBG(X) printf(__FILE__":%d DBG("#X")n", __LINE__)
int main ()
{
    DBG(this is a test);
}

这会产生输出:

test.cc:7 DBG(this is a test)

编辑:您必须访问源文件或存储源文件。一旦存储了文件,打印正确的行就很简单了。单向:

#define PROGRAM_PRINT_INIT(X) 
    static ProgramPrint pp = ProgramPrint(X)
#define DBG(X) std::cerr << "[" << pp.name << ":" << X << "]" 
                         << pp.file[X] << std::endl
struct ProgramPrint {
    std::string name;
    std::vector<std::string> file;
    ProgramPrint (const char *filename) : name(filename) {
        std::ifstream in(filename);
        std::string line;
        while (getline(in, line)) file.push_back(line);
    }
};

请注意,vector索引从零开始,因此相应地使用DBG()

是的,C/C++不是为这个而生的。但如果你真的想看看你能把事情弯曲到什么程度,这是一个建议。

假设您想编译test.cpp进行测试。在编译源代码文件之前,我们需要将源代码行的cstring数组预先添加到源代码文件中。我们将在一个单独的文件test_temp.cpp中执行此操作,并调用数组test_code。

将以下内容放在一个文件中:code.awk(这样可以更容易地恢复)。

BEGIN {
    for (i = 0; i < 128; i++) {
        table = sprintf("%s%c", table, i);
    }
    print("= {""")
}
{
    printf(","")
    for(j=1; j<=length($1); j++) {
        c = substr($1,j,1)
        printf("\x%x", index(table, c) - 1)
    }
    printf(""n")
}
END {
    printf("};n")
}

通过引用ASCII字符的"表",这将为每个字符使用(十六进制)ASCII值(例如"\x41"表示"a"),以防出现制表符等内容,这些内容可能在源代码中,但应在C/C++字符串文本中转义。

要进行编译,请在命令行(或makefile)中键入

echo "char* TEST_CODE[]" > test_temp.cpp
awk -f code.awk test.cpp >> test_temp.cpp
cat test.cpp >> test_temp.cpp
g++ -o test test_temp.cpp
rm test_temp.cpp

如果你想得到源代码文件的第80行(基于1),你可以写

TEST_CODE[80]

注意,这发生在预处理器命令之前。通过在每种情况下从TEST_CODE更改数组名称,可以对多个文件和头文件执行此操作。

这确实有漏洞,但在常见情况下也能起作用。

注意:由于char*/string文字转换,g++可能会发出A LOT编译器警告,但您可以使用-w标志关闭这些警告。