web-dev-qa-db-fra.com

convertir un nom de variable en chaîne en C++

Je voudrais sortir des données dans un fichier. Par exemple, supposons que j'ai deux vecteurs de doubles:

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

existe-t-il un moyen simple de le générer dans un fichier de sorte que la première ligne contienne les en-têtes «data1» et «data2» suivis du contenu réel. La fonction qui produit les données sera transmise à différents tableaux. Il est donc impossible de coder en dur le nom de l'en-tête. Dans l'idéal, j'aimerais convertir le nom de la variable en une chaîne, puis afficher cette chaîne suivie du contenu du tableau vectoriel. Cependant, je ne suis pas sûr de savoir comment convertir le nom de variable 'data1' en chaîne, ou même s'il est facile de le faire (en lisant les forums, je suppose que c'est impossible). Si ce n'est pas possible, une alternative peut être d'utiliser un conteneur associatif tel que map ou peut-être plus simplement un conteneur "paire".

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

Toute suggestion serait la bienvenue!

20
Wawel100

Vous pouvez utiliser le préprocesseur "stringify" # pour faire ce que vous voulez:

#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

(Désolé pour printf, je n'ai jamais maîtrisé <iostream>. Mais cela devrait suffire.)

37
sarnold

essaye ça:

#define GET_VARIABLE_NAME(Variable) (#Variable)

// dans les fonctions

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

Vous pouvez utiliser le préprocesseur, il existe un jeton stringify, mais il n'est disponible que depuis la source, pas pour une fonction (vous obtiendrez le nom de l'argument).

2
Puppy

Légèrement adapté de la réponse de @ sarnold, en C++:

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

Un exemple de programme qui utilise ceci:

int main() {
    int foo = 1;
    DEBUG(foo);

    return 0;
}
2
thiagowfx

J'aurais pensé que la réponse évidente était de faire en sorte que la fonction qui effectue la sortie prenne le texte du titre en tant que paramètre de chaîne.

1
anon

Pour ce cas, j'ai fait nameof () macro. Il retourne le nom std :: string d'une variable, d'un type ou d'un membre. Cela fonctionne comme nameof () en C #.

Par exemple:

#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
0
Dmitry Bravikov

J'ai eu le même problème. Après un peu d'expérimentation, j'ai créé les macros suivantes qui convertissent les noms de variables, champs, fonctions, méthodes et types en chaînes.

#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)

Le code utilise une conversion par opérateur et par virgule pour forcer le compilateur à vérifier si la variable, la fonction, etc. La bonne chose est que cela fonctionne bien aussi avec les variables non initialisées. Je l'ai testé à la fois sur VC et sur GCC avec toutes les options pédagogiques que j'ai découvertes sans aucun message d'avertissement.

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

int Variable=GetAndPrintValue(MACRO_VARIABLE_TO_STRING(Variable));

J'utilise ce code lorsque j'écris des analyseurs qui lisent les données du flux d'entrée et si la variable analysée est hors limites, une exception avec le nom de la variable qui a échoué lors de mes vérifications de validité est levée.

0
Timmy_A