mikrocontroller.net

Forum: Compiler & IDEs #define für Stringersetzung


Autor: Steffen (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

der Betreff klingt zwar komisch, ich weiß aber nicht wie ich es anders 
nennen soll.

Folgende Problematik: Ich habe eine Progmem-Variable die einen Text 
enthält und für eine Webseite ist (siehe Codesammlung):
PROGMEM char Variable[] = {
...
" ... width=\"100\"..."
...};
Dieses "width" ist zur Compilezeit bekannt und wird auch in einigen 
Berechnungen verwendet. Dazu möchte ich in etwa folgendes:
#define BREITE 100
#define STR_BREITE "100"
Kann ich das STR_BREITE irgendwie aus BREITE ableiten? Beispielsweise 
über ein weiters Makro?

Ziel ist:
in der Progmem-Variable z.B. sowas wie:
"...width=\"" STR(BREITE) "\"..."

und in einer Berechnung:
xyz = BREITE / a;

Dazu konnte ich irgendwie nichts finden.

Steffen.

Autor: yalu (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
#define STR2(x) #x
#define STR(x) STR2(x)

Autor: Steffen (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
super, das werde ich heute Abend gleich mal probieren.

Steffen.

Autor: peda (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Und hat jemand sowas schonmal gemacht?

Ich brauchs auch öfter.

Mit dem Post von yalu kann ich garnichts anfangen.


Peter

Autor: Rolf Magnus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Und hat jemand sowas schonmal gemacht?

Ja, viele.

> Mit dem Post von yalu kann ich garnichts anfangen.

Warum nicht?

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
peda wrote:
> Und hat jemand sowas schonmal gemacht?
>
> Ich brauchs auch öfter.

Sicher

>
> Mit dem Post von yalu kann ich garnichts anfangen.

Das ist der Präprozessor 'Stringize' Operator.
Im Web findst du haufenweise Beschreibungen und
Beispiele dazu.

Der springende Punkt ist der # Operator.
Und ja man muss den Umweg über ein Zwischnmakro
gehen.

Autor: peda (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wie es scheint, ist es unendlich schwer, mal ein passendes Beispiel zu 
posten.

In welche Richtung geht das überhaupt String->Zahl oder umgekehrt oder 
geht beides?


Peter

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
peda wrote:
> Wie es scheint, ist es unendlich schwer, mal ein passendes Beispiel zu
> posten.

Wieso. Da oben wurde doch schon eines 'angepostet'

#define STR2(x) #x
#define STR(x) STR2(x)

#define BREITE 100
#define STR_BREITE STR(BREITE)

War das jetzt so schwer zu erraten?

> In welche Richtung geht das überhaupt String->Zahl oder umgekehrt oder
> geht beides?

Ersetzung eines Textes durch denselben Text mit " rundherum.
Aus 100 wird so "100". Aus abcd wird so "abcd"

Drum heist der Operator auch Stringize. Weil er aus einem
normalen Text denselben Text als C verwertbaren String macht.
Das hat erstmal nichts mit Zahlen zu tun. Der Präprozessor
macht Textersetzungen. Welchen Text er durch welchen anderen
Text ersetzt, ist ihm erst mal völlig egal.

Autor: peda (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
So, jetzt hab ich endlich kapiert, was yalu meinte.

Es war halt der 2.Schritt vor dem ersten.
Die Bedeutung des # ist wohl noch seltener erklärt, als die des ##. Ich 
kannte es bisher noch nicht.

#include <reg51.h>


#define VERSION_H       0A
#define VERSION_L       1B

#define STR2(x) #x
#define STR(x) STR2(x)

#define VERSION         VERSION_H##.##VERSION_L
#define VERSION_S       STR(VERSION)

#define VERSION_HN      0x##VERSION_H
#define VERSION_LN      0x##VERSION_L


void main(void)
{
  char s[] = VERSION_S;

  P1 = s[1];
  P2 = VERSION_HN;
  P3 = VERSION_LN;

  for(;;);
}


Peter

Autor: yalu (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Wie es scheint, ist es unendlich schwer, mal ein passendes Beispiel
> zu posten.

Wenn's an Beispielen gebricht, hier ist ein weiteres relativ
nützliches:

Ich möchte zu Debug-Zwecken während des Programmlaufs den Inhalt der
Variablen eine_int_variable ausgeben. Dies geht bspw. so:
printf("eine_int_variable = %d\n", eine_int_variable);
Weil ich zu faul bin, den langen Variablennamen zweimal zu tippen,
bastle ich mir einfach folgendes Makro:
#define DBG_INT(v) printf(STR(v)" = %d\n", v)
und schreibe dann nur noch
DBG_INT(eine_int_variable);
Das funktioniert nicht nur mit Variablen, sondern mit beliebigen
Ausdrücken. Hier ein vollständiges Beispiel:
#include <stdio.h>
#include <string.h>
#include <math.h>

#define STR2(x) #x
#define STR(x) STR2(x)

#define DBG_INT(v) printf(STR(v)" = %d\n", v)
#define DBG_DBL(v) printf(STR(v)" = %g\n", v)

int main(void) {
  int i;
  double d;

  i = 10 * 10;
  DBG_INT(i);

  d = sqrt(2.);
  DBG_DBL(d);

  DBG_DBL(4 * asin(d/2));
  DBG_INT(2 * i + strlen("test"));

  return 0;
}
Das Programm liefert folgende Ausgabe:
i = 100
d = 1.41421
4 * asin(d/2) = 3.14159
2 * i + strlen("test") = 204
Schick, oder?

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.