【问题标题】:converting a variable name to a string in C++在 C++ 中将变量名转换为字符串
【发布时间】:2011-03-24 03:29:59
【问题描述】:

我想将一些数据输出到文件中。例如假设我有两个双精度向量:

vector<double> data1(10);
vector<double> data2(10); 

有没有一种简单的方法可以将其输出到文件中,以便第一行包含标题“data1”和“data2”,然后是实际内容。该功能 输出数据将传递给各种不同的数组,因此对名称进行硬编码 标题是不可能的 - 理想情况下我想转换变量名 到某个字符串,然后输出该字符串,后跟向量数组的内容。但是,我不确定如何将变量名“data1”转换为字符串, 或者确实可以轻松完成(从阅读论坛我猜它不能) 如果这是不可能的,另一种选择可能是使用关联 容器,例如 map 或更简单的“pair”容器。

pair<vector<double>,string> data1(10,'data1');  

欢迎提出任何建议!

【问题讨论】:

  • 我想知道你想要达到什么目的。如果它是任意数量的数据,命名它的每个部分对你没有任何好处,因为无论如何都必须手工完成。您的第二个解决方案可能就是您正在寻找的解决方案。
  • 哇,这有点棘手,你可以尝试做的一件事是创建类或结构,它们的元素是字符串'name'。

标签: c++ string variables map std-pair


【解决方案1】:

你可以使用预处理器“stringify”# 来做你想做的事:

#include <stdio.h>

#define PRINTER(name) printer(#name, (name))

void printer(char *name, int value) {
    printf("name: %s\tvalue: %d\n", name, value);
}

int main (int argc, char* argv[]) {
    int foo = 0;
    int bar = 1;

    PRINTER(foo);
    PRINTER(bar);

    return 0;
}


name: foo   value: 0
name: bar   value: 1

(对不起printf,我从来没有掌握&lt;iostream&gt;的窍门。但这应该足够了。)

【讨论】:

    【解决方案2】:

    试试这个:

    #define GET_VARIABLE_NAME(Variable) (#Variable)
    

    //在函数中

    int var=0;    
    char* var_name= GET_VARIABLE_NAME(var);
    

    【讨论】:

      【解决方案3】:

      我遇到了同样的问题。经过一些实验,我创建了以下宏,将变量、字段、函数、方法和类型的名称转换为字符串。

      #define MACRO_VARIABLE_TO_STRING(Variable) (void(Variable),#Variable)
      
      #define MACRO_FUNCTION_TO_STRING(Function) (void(&Function),#Function)
      
      #define MACRO_METHOD_TO_STRING(ClassName,Method) (void(&ClassName::Method),#Method)
      
      #define MACRO_TYPE_TO_STRING(Type) (void(sizeof(Type)),#Type)
      

      代码使用逗号运算符和void转换来强制编译器检查变量、函数等是否真的存在。好消息是它也适用于未初始化的变量。我在 VC 和 GCC 上使用我发现的所有迂腐选项对其进行了测试,但没有任何警告消息。

      int GetAndPrintValue(const char* VariableName)
      {
         std::cout << VariableName << std::endl;
         return 10;
      }
      
      int Variable=GetAndPrintValue(MACRO_VARIABLE_TO_STRING(Variable));
      

      当我编写从输入流中读取数据的解析器时,我会使用这样的代码,如果解析的变量超出范围,它会抛出一个异常,其变量名称未能通过我的有效性检查。

      【讨论】:

        【解决方案4】:

        稍微改编自@sarnold 的回答,用于 C++:

        #define DEBUG(x) std::cout << #x << " = " << x << std::endl;
        

        一个使用这个的示例程序:

        int main() {
            int foo = 1;
            DEBUG(foo);
        
            return 0;
        }
        

        【讨论】:

          【解决方案5】:

          您可以使用预处理器,有一个 stringify 标记,但它只能从源获得,而不是函数(您会得到参数名称)。

          【讨论】:

            【解决方案6】:

            我有一个类似的任务。在 Qt 中,我厌倦了在写入 qDebug() 时不断将变量名称写为没有自动完成功能的字符串。 在对不同的宏和函数进行了大量试验和错误之后,我发现这个宏很好用:

            #define PRINT(x) ", " << #x << ": " << x
            

            示例用法:

            int someVariable = 42;
            double anotherVariable = 13.37;
            qDebug().nospace() << "Some text" << PRINT(someVariable) << PRINT(anotherVariable);
            

            输出:

            Some text, someVariable: 42, anotherVariable: 13.37
            

            我想这(或类似的东西)也适用于std::cout

            聚会有点晚了,但我希望这可以帮助任何人!

            【讨论】:

              【解决方案7】:

              我认为显而易见的答案是让执行输出的函数将标题文本作为字符串参数。

              【讨论】:

              • 理想情况下,我希望能够在没有包含变量名称的字符串参数的情况下调用执行输出的函数。
              【解决方案8】:

              对于这种情况,我制作了nameof() 宏。它返回变量、类型或成员的 std::string 名称。它的工作方式类似于 C# 中的 nameof()。

              例如:

              #include "nameof.h"
              
              std::vector<double> data1(10);
              std::string name = nameof(data1); // "data1"
              
              struct Foo1
              {
                  struct Foo2
                  {
                      Foo1* foo1;
                  };
              
                  Foo1* foo1;
                  Foo2 foo2;
              };
              
              name = nameof(Foo1::foo1->foo2.foo1); // "foo1"
              
              name = nameof(123); // std::logic_error exception
              

              【讨论】:

                猜你喜欢
                • 2015-10-25
                • 2011-08-27
                • 2010-12-04
                • 2020-04-14
                • 2011-08-02
                • 2016-04-26
                • 1970-01-01
                相关资源
                最近更新 更多