Interpretation von Zeichenketten



  • 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
    


  • 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



  • folglich duerfte ein Aufruf von get_const innerhalb von z.B. main() ins leere
    fuehren oder taeusch ich mich da?

    also eigentlich kann man in keinem fall was aufrufen, die makros sind nur für den
    preprocessor und sind im fertigen programm nicht mehr sichtbar. Um im source code
    klarzumachen was ein macro und was eine function ist werden macros normal groß
    geschrieben.

    der gedanke bei folgendem snippet ist, das macro neu zu definieren, und die
    konstanten mit gleichem suffix zu gruppieren. die macros werden eigentlich,
    in der reihenfolge abgearbeitet was bedeutet:

    #define get_const(x) x
            //ab jetzt wird jedes vorkommen von get_const(x)
            //durch x ersetzt
        #undef get_const
            //ab jetzt meldet jedes vorkommen von get_const
            //einen fehler
        #define get_const(x) x##_constant
            //ab jetzt wird jedes vorkommen von get_const(x)
            //durch x##_constant ersetzt
        #undef get_const
            //ab jetzt meldet jedes vorkommen von get_const
            //einen fehler
        #define get_const(x) x##_first
            //ab jetzt wird jedes vorkommen von get_const(x)
            //durch x##_first ersetzt
        #undef get_const 
            //ab jetzt meldet jedes vorkommen von get_const
            //einen fehler
    

    ob es undefiniert wird, spielt für bereits ersetzte text stellen keine rolle.
    da die macros zur laufzeit nichtmehr verfügbar sind war die überlegung wie in
    folgendem post die konstanten zur laufzeit verfügbar zu machen.

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

    wirklich interresant ist eigentlich der punkt wo aus dem definierten namen
    ein string wird und dass passiert:

    //.- hier
                         // v
    #define makeEntry(x)   {#x,x}
    


  • Ah i.O., verstehe, so meinst du das.

    Aber alles in allem kann das eigentliche Ausgangsproblem des Threads als _geloest_ betrachtet werden. 🕶 👍

    Danke nochmals fuer die Aufmerksamkeit


Anmelden zum Antworten