Interpretation von Zeichenketten
-
hauts mir bitte nicht die finger ab
#include <stdio.h> #include <stdlib.h> #include <string.h> #define first_constant 1 #define second_constant 2 #define error_constant (-1) #define TO_STR(s) #s #define BEGIN_CASE if(0) #define CASE(x) else if(strcmp(constant,#x) == 0) #define END_CASE int return_constant_value(char *constant){ int constant_value = error_constant; BEGIN_CASE; CASE(first_constant){ constant_value = first_constant; } CASE(second_constant){ constant_value = second_constant; } END_CASE; return constant_value; } int main(void) { printf("%i\n",return_constant_value(TO_STR(first_constant))); printf("%i\n",return_constant_value(TO_STR(second_constant))); printf("%i\n",return_constant_value("first_constant")); printf("%i\n",return_constant_value("second_constant")); printf("%i\n",return_constant_value(" ")); return EXIT_SUCCESS; }
-
Ein Bareword ist im Prinzip nur ein fuer sich stehendes Wort.
Erwaehnt werden sollte vielleicht noch, das die
#define
Konstanten im Quellcode bzw. im resultierenden Binary der aufrufenden Funktion nicht sichtbar sind. Sichtbar ist lediglich die Funktion
return_constant_value
.
Auch wenn es sich hierbei nicht um ein Perl Forum handelt, versuche ich dennoch das Problem mit Hilfe eines Perl Scriptes offenzulegen.
use Modul; # Einbinden des entspr. Modules (inkl. der Fkt. return_constant_value) no strict 'refs'; # Erlaubt die Verwendung von Barewords $retval = return_constant_value(first_constant); # Sollte 1 returnieren print "\$retval - $retval\n";
Soweit zu Perl.
Innerhalb der C-Funktion
return_constant_value
sollte nun das Argument
first_constant
z.B. als Datentyp char oder char * gehandelt werden.
An dieser Stelle kommt die Interpolation ins Spiel welche aus der Zeichenkette
'first_constant' automatisch (oder manuell) die #define Konstante 'first_constant' ableitet bzw. erkennt und entsprechend 1 an die Variableconstant_value
assoziert.
Ich hoffe das hift.
Danke
-
Sorry ich war zu langsam aber die Frage bleibt
-
mrxy schrieb:
Innerhalb der C-Funktion
return_constant_value
sollte nun das Argument
first_constant
z.B. als Datentyp char oder char * gehandelt werden.
Übergib doch gleich nen char*:
int return_constant_value(char *s)
mrxy schrieb:
An dieser Stelle kommt die Interpolation ins Spiel welche aus der Zeichenkette
'first_constant' automatisch (oder manuell) die #define Konstante 'first_constant' ableitet bzw. erkennt und entsprechend 1 an die Variableconstant_value
assoziert.
Ich hoffe das hift.
DankeDu meinst eher Umwandlung, ne? Dafür gibt es Funktionen wie atoi, itoa, usw.
-
Interpolation heißt fuer mich immer noch u.a. Umgestaltung.
Aufruf der Funktion:
$retval = return_constant_value(first_constant);
oder
$retval = return_constant_value("first_constant");
Innerhalb von C soll nun folgendes passieren:
Das Argument (first_constant) wird zunaechst mit einem Parameter entgegengenommen.
Im Falle von char handelt es sich also um eine _Zeichenkette_.Als naechstes sollte diese Zeichenkette umgestaltet (interpoliert) werden sodass
der Variablenconstant_value // innerhalb von return_constant_value
der Wert von
#define first_constant ...
also 1 zugewiesen wird.
Funktionen wie atoi() helfen mir da leider nicht weiter auch der Ansatz von c_newbie hift mir leider nicht weiter.
Danke
-
ich denke aber dass der 2. beitrag von mir genau das macht was du eben beschrieben hast oder steh ich auf dem schlauch?
-
Ja im Grunde stimmt das schon. Aber alternativ koennt ich auch folgendes schreiben was deinem Konzept im Resultat gleicht.
int return_constant_value(char *constant){ int constant_value = -1; if (!strncmp(constant, "first_constant")) constant_value = first_constant; .... .... .... return constant_value; }
Das Problem aber ist dass ich ne Menge Konstanten habe und dementsprechend viele case- bzw. if-Zweige/Konstrukte kreieren muesste
Meine Hoffnung war das ich mit einer Instruktion wie dieser (vereinfacht)
auskommen wuerde:constant_value = constant // Oder mit einer Hilfsfunktion...
Im Idealfall sollte constant_value nun 1 enthalten. Wuerde ich als Argument 'secon_constant' uebergeben sollte 'constant_value' als Ergebnis 2 liefern.
Danke
-
eine andere Möglichkeit würde so in die Richtung gehen
dann kannst da drüber loopen und den Eintrag suchen der
passt.#define makeEntry(x) {#x,x} typedef struct MYConstants{ char *name; int data; }myConstants; myConstants konst[] = { makeEntry(first_constant) ,makeEntry(second_constant) ,makeEntry(x) ,makeEntry(x) ,makeEntry(x) };
dass passt natürlich auch super in ne hashmap, also string rein zahl raus.
aber normal hat man nicht so mega viele konstanten oder?lg
-
Ich spiel mal n bisschen.mit deinen Ansaetzen...
Melde mich wieder.
Danke
-
Ok, folgendes funktioniert
#define first_constant 1 #define secon_constant 2 #define get_const(x) x##_constant int main(void) { return get_const(first); /* Returniert mit 1 */ }
Aber 2 Probleme bleiben bestehen.
1. Die Uebergabe als Zeichenkette funktioniert nicht (get_const("first"))
Wie also variable Argumente uebergeben?2. Ich bin auf das Suffix '_constant' angewiesen. Was aber machen bei Konstanten
mit einem anderen oder gar keinem Suffix?Irgendwie muesste man das doch dem Praeprozessor beibringen koennen, oder?
Danke
-
#define get_const(x) x"_constant"
hilft evtl. und natürlich
-
"Irgendwie muesste man das doch dem Praeprozessor beibringen koennen, oder?"
evtl. solltest dir mal m4 anschauen denk da ist sowas möglich
-
Ja, an M4 dachte ich auch schon.
wikipedia, c in a nutshell und aehnliches liefert nichts akzeptables.Naja, mal sehen...
Danke
-
Ach bezueglich deiner Frage mit den Konstanten..
Doch es sind ne Menge. Es werden mehrere Header-Files inkludiert und dessen
Funtionsdeklarationen, defines... in den Namensraum der Perl-Anwendung exportiert.Danke
-
Nun ja, ziemlich simpel aber effektiv:
#include <stdio.h> #define first_constant 1 #define constant_first 2 #define first 3 #define get_const(x, y) x##y int main(void) { int x = get_const(first, _constant); int y = get_const(constant, _first); int z = get_const(first, ); printf("[%d, %d, %d]\n", x, y, z); return 0; }
So klappts auch mit dem Praeprocessor
Danke
-
hi,
ich würd eher dass zweite argument in das macro mit rein bringen, sonst mußt es
ja wieder für jede konstante dazu schreiben.#include <stdio.h> #define first_constant 1 #define constant_first 2 #define first 3 #define _constant #define _first #define get_const_c(x) x##_constant #define get_const_f(x) x##_first #define get_const(x) x int main(void) { int x = get_const_c(first); int y = get_const_f(constant); int z = get_const(first); printf("[%d, %d, %d]\n", x, y, z); return 0; }
-
Nein, nein. Das zweite Argument
fuer die Praeprozessordirektive
get_const(x, y) x##y
ist optional. Alternativ koennte ich also auch folgendes coden:
#include <stdio.h> #define first_constant 1 #define constant_first 2 #define first 3 #define get_const(x, y) x##y int main(void) { int x = get_const(first_constant, ); int y = get_const(constant_first, ); int z = get_const(first, ); printf("[%d, %d, %d]\n", x, y, z); return 0; }
Bei einer Definition wie der folgenden
#define get_const(x, y) x##
meckert der Compiler bzw. Praeprozessor
error: '##' cannot appear at either end of a macro expansionEs wird also hinter der Rautesequenz noch etwas erwartet soetwas wie '_constant'
oder '_first' wie du auch geschrieben hast.Etwas wie
#define get_const(x) x##""
funtioniert auch nicht da die Substitution nichts mit Strings zutun hat.
Danke
-
Das hab ich vergessen zu schreiben.
Bei deiner Version wuerd ich mich wieder vom Suffix abhaengig machen (_constant && _first) und genau das moechte ich vermeiden.
Danke
-
sowas hätt ich evtl noch im angebot
#define get_const(x) x #include "x.h" #undef get_const #define get_const(x) x##_constant #include "x_constant.h" #undef get_const #define get_const(x) x##_first #include "x_first.h" #undef get_const
-
Wie schon erwaehnt, wuerde ich mich bei einem Ansatz wie
#define get_const_c(x) x##_constant #define get_const_f(x) x##_first
abhaengig von den Namensgebungen der Ersatztexte machen.
Die beiden defines
#define _constant #define _first
sind optional.
Ein einfaches
#define get_const(x) x
ist schon ausreichend wie auch
#define get_const(x, y) x##y
Die beiden bringen das gewuenschte Ergebnis!
Deiner letzter Post
#define get_const(x) x #include "x.h" #undef get_const #define get_const(x) x##_constant #include "x_constant.h" #undef get_const #define get_const(x) x##_first #include "x_first.h" #undef get_const
duerfte nicht funktionieren, da der PP ja deine get_const Makros 'undefiniert' bevor das Programm kompiliert wird, folglich duerfte ein Aufruf von get_const innerhalb von z.B. main() ins leere fuehren oder taeusch ich mich da?
Danke