Interpretation von Zeichenketten



  • mrxy schrieb:

    return_constant_value(first_constant);
    

    Wenn die Funktion das gleiche zurückgibt, was du in sie reinsteckst, dann kannst du die Funktion auch weglassen und gleich first_constant antelle von return_constant_value(first_constant) schreiben.
    Das ist keine Interpolation, sondern Prozessorbeschäftigungstherapie.



  • 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 Variable

    constant_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 Variable

    constant_value
    

    assoziert.
    Ich hoffe das hift.
    Danke

    Du 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 Variablen

    constant_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

    http://en.wikipedia.org/wiki/C_preprocessor



  • "Irgendwie muesste man das doch dem Praeprozessor beibringen koennen, oder?"

    evtl. solltest dir mal m4 anschauen denk da ist sowas möglich

    http://www.gnu.org/software/m4/



  • 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 expansion

    Es 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
    

Anmelden zum Antworten