Forum: Compiler & IDEs #define für Stringersetzung


von Steffen (Gast)


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):
1
PROGMEM char Variable[] = {
2
...
3
" ... width=\"100\"..."
4
...};
Dieses "width" ist zur Compilezeit bekannt und wird auch in einigen 
Berechnungen verwendet. Dazu möchte ich in etwa folgendes:
1
#define BREITE 100
2
#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:
1
"...width=\"" STR(BREITE) "\"..."

und in einer Berechnung:
1
xyz = BREITE / a;

Dazu konnte ich irgendwie nichts finden.

Steffen.

von yalu (Gast)


Lesenswert?

1
#define STR2(x) #x
2
#define STR(x) STR2(x)

von Steffen (Gast)


Lesenswert?

super, das werde ich heute Abend gleich mal probieren.

Steffen.

von peda (Gast)


Lesenswert?

Und hat jemand sowas schonmal gemacht?

Ich brauchs auch öfter.

Mit dem Post von yalu kann ich garnichts anfangen.


Peter

von Rolf Magnus (Gast)


Lesenswert?

> Und hat jemand sowas schonmal gemacht?

Ja, viele.

> Mit dem Post von yalu kann ich garnichts anfangen.

Warum nicht?

von Karl H. (kbuchegg)


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.

von peda (Gast)


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

von Karl H. (kbuchegg)


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.

von peda (Gast)


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.

1
#include <reg51.h>
2
3
4
#define VERSION_H       0A
5
#define VERSION_L       1B
6
7
#define STR2(x) #x
8
#define STR(x) STR2(x)
9
10
#define VERSION         VERSION_H##.##VERSION_L
11
#define VERSION_S       STR(VERSION)
12
13
#define VERSION_HN      0x##VERSION_H
14
#define VERSION_LN      0x##VERSION_L
15
16
17
void main(void)
18
{
19
  char s[] = VERSION_S;
20
21
  P1 = s[1];
22
  P2 = VERSION_HN;
23
  P3 = VERSION_LN;
24
25
  for(;;);
26
}


Peter

von yalu (Gast)


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:
1
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:
1
#define DBG_INT(v) printf(STR(v)" = %d\n", v)
und schreibe dann nur noch
1
DBG_INT(eine_int_variable);
Das funktioniert nicht nur mit Variablen, sondern mit beliebigen
Ausdrücken. Hier ein vollständiges Beispiel:
1
#include <stdio.h>
2
#include <string.h>
3
#include <math.h>
4
5
#define STR2(x) #x
6
#define STR(x) STR2(x)
7
8
#define DBG_INT(v) printf(STR(v)" = %d\n", v)
9
#define DBG_DBL(v) printf(STR(v)" = %g\n", v)
10
11
int main(void) {
12
  int i;
13
  double d;
14
15
  i = 10 * 10;
16
  DBG_INT(i);
17
18
  d = sqrt(2.);
19
  DBG_DBL(d);
20
21
  DBG_DBL(4 * asin(d/2));
22
  DBG_INT(2 * i + strlen("test"));
23
24
  return 0;
25
}
Das Programm liefert folgende Ausgabe:
1
i = 100
2
d = 1.41421
3
4 * asin(d/2) = 3.14159
4
2 * i + strlen("test") = 204
Schick, oder?

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.