String aneinander reihen

Gast #638103
Lesenswert?

Hallo,

eine kleine Frage:

Ich möchte mehrere einzelne Strings aneinander hängen.

DisplayRAM = "Drehzahl:     " " U/min             " "Spannung:     " 
"Volt             " ;

Das geht auch so weit ganz gut.

Nur wie kann ich jetzt dieses erzeugen?

volatile unsigned int Zahl = 0;
volatile unsigned char string[5];
...

itoa( Zahl, string, 10);

DisplayRAM = "Drehzahl:     " string " U/min             " "Spannung: 
" string "Volt             " ;

Ich möchte also zum String die Werte der Zahl einfügen.

Gruß Toby
Persönliche Seite #638117
Lesenswert?

Deine aneinandergehängten Strings sind nicht wirklich aneinandergehängte 
Strings, sondern eine einzige große Stringkonstante.
Um das Zusammenfügen kümmert sich bereits der Preprocessor.

Um sich verändernde Werte an Strings anzuhängen, muss eine andere 
Vorgehensweise verwendet werden.

Einerseits benötigst Du einen ausreichend großen Puffer, der das 
Endergebnis aufnehmen soll, andererseits musst Du geeignete Funktionen 
zur Stringverarbeitung verwenden.
1
char buf[100];  // muss ausreichend groß sein!
2
char string[6]; // muss für Ausgabe von unsigned int reichen 
3

4

5
itoa(Zahl1, string, 10);
6

7
buf[0] = '\0';
8

9
strcat(buf, "Drehzahl: ");
10
strcat(buf, string);
11
strcat(buf,  " U/min  ");
12
strcat(buf,  " Spannung:  ");
13

14
itoa(Zahl2, string, 10);
15
strcat(buf, string);
16

17
strcat(buf, "Volt             ");

(die Formatierung der Leerzeichen etc. solltest Du Dir nochmal näher 
ansehen).

Bei Aufruf von itoa mit einem unsigned Int muss der übergebene Puffer 
übrigens Platz für sechs und nicht nur für fünf Zeichen bieten - ein 
unsigned int selbst kann eine fünfstellige Zahl sein, und die 
stringterminierende Null muss auch noch Platz finden.

Wenn ausreichend Programmspeicher zur Verfügung steht, lässt sich 
natürlich auch ein printf-Derivat einsetzen, was den Vorteil der auf 
definierbare Feldbreiten formatierten Ausgabe der numerischen Werte 
hätte.
Persönliche Seite #638148
Lesenswert?

Nein, strcat hat exakt zwei Argumente. Den Adressoperator solltest Du 
übrigens auch weglassen.

Du musst also strcat für jedes anzuhängendes Stringfragment erneut 
aufrufen - wobei es Dir unbenommen bleibt, Stringkonstanten automatisch 
vom Preprocessor zusammenfassen zu lassen (U/min und Spannung).

Sofern Du einen AVR mit seiner praktischen Harvard-Architektur 
verwendest, solltest Du auch daran denken, daß Stringkonstanten im RAM 
abgelegt werden. Du solltest also darauf achten, diese via PROGMEM zu 
deklarieren und zu nutzen, dafür sollte dann ein strcat_P existieren:
1
char buf[100];  // muss ausreichend groß sein!
2
char string[6]; // muss für Ausgabe von unsigned int reichen 
3

4

5
itoa(Zahl1, string, 10);
6
buf[0] = '\0';
7

8
strcat_(buf, PSTR("Drehzahl: "));
9
strcat(buf, string);
10
strcat_P(buf,  PSTR(" U/min  "));
11
strcat_P(buf,  PSTR(" Spannung:  "));
12

13
itoa(Zahl2, string, 10);
14
strcat(buf, string);
15

16
strcat_P(buf, PSTR("Volt             "));

Für Deine zur Laufzeit erzeugten Strings musst Du natürlich das 
"normale" strcat verwenden.
#638222
Lesenswert?

Brauchst du den String eigentlich sicher an einem Stück?
Bei RS232 oder LCD-Ausgabe isses normalerweise möglich die Teilstrings 
einzeln nacheinander auszugeben.

also
  uart_print_P(PSTR("Drehzahl: "));
  uart_print_int(drehzahl);
  uart_print_P(PSTR("  U/min "));
 usw.

/Ernst
Gast #638232
Lesenswert?

Hallo,

ich brauche den String, um ihn auf einem LED Array anzuzeigen.

Eine Frage noch, in welcher Lib ist die Funktion "strcat" mit drin?

Ich bekomme noch den Fehler:

..../main.c:521: undefined reference to `strcat_'


Gruß Toby
Gast #638254
Lesenswert?

Hallo Jörg,

habe es schon gesehen, da fehlte ein P.

Es geht jetzt wunderbar!

Eine letzte Sache noch:

Ich habe es jetzt so geschrieben:


volatile uint8_t *DisplayRAM = "Drehzahl: 0000 U/min 
Spannung: 0,00 Volt             ";
volatile unsigned int Zahl1 = 0;
volatile unsigned int Zahl2 = 0;
char buf[64];  // (habe max.64 Zeichen)
char string[6]; // muss für Ausgabe von unsigned int reichen

itoa(Zahl1, string, 10);
  buf[0] = '\0';

  strcat_P(buf, PSTR("Drehzahl: "));
  strcat(buf, string);
  strcat_P(buf,  PSTR(" U/min           "));
  strcat_P(buf,  PSTR("Spannung: "));

  itoa(Zahl2, string, 10);
  strcat(buf, string);

  strcat_P(buf, PSTR(" Volt              "));

  DisplayRAM = buf;

Angezeigt wird nun:

"Drehzahl: XXXX U/min           Spannung: XXX Volt              "

wie bekomme ich nun noch hier:             ^ ein Komma dazwischen?

"Drehzahl: XXXX U/min           Spannung: X,XX Volt              "

Da muß ich doch diese Funktion :
itoa(Zahl2, string, 10);
strcat(buf, string);
zerlegen, nach den ersten Ziffern ein "," schreiben, und dann die 
letzten Ziffern, richtig?

Gruß Toby
Gast #638257
Lesenswert?

Hallo Karl Heinz,

ich habe schon ein C Buch (C für Mikrocontroller, von Franzis), 
allerdings ist es nicht so toll, da mir eigentlich immer die Beispiele 
genau zu meinem Problem fehlen.

Wenn ich die Beispiele hier lese, verstehe ich es eigentlich recht 
schnell.
Ich nutze ja meistens auch die Suchfunktion, bevor ich etwas spezielles 
frage. ;-)

Trotzdem danke.

Gruß Toby
Moderator Persönliche Seite #638266
Lesenswert?

TobyTetzi wrote:

> volatile uint8_t *DisplayRAM = "Drehzahl: 0000 U/min
> Spannung: 0,00 Volt             ";

Das volatile ist hier sehr wahrscheinlich überflüssig (und könnte dir
umständlichen Code erzeugen).  Der Datentyp darstellbarer Zeichen
sollte immer als "char" deklariert werden.

> volatile unsigned int Zahl1 = 0;
> volatile unsigned int Zahl2 = 0;

Stellt sich ebenfalls die Frage, wofür das volatile hier gut ist.

> Angezeigt wird nun:
>
> "Drehzahl: XXXX U/min           Spannung: XXX Volt              "
>
> wie bekomme ich nun noch hier:             ^ ein Komma dazwischen?
1
#include <stdlib.h>
2

3
...
4
  div_t d;
5

6
  d = div(Zahl2, 10);
7
  itoa(d.quot, string, 10);
8
  strcat(buf, string);
9
  strcat_P(buf, PSTR(","));
10
  itoa(d.rem, string, 10);
11
  strcat(buf, string);
12
  strcat_P(buf, PSTR(" Volt              "));
13

14
...

Zwar benutzt div() vorzeichenbehaftete Integerzahlen, während deine
Werte unsigned sind, aber itoa() benutzt ebenfalls int.  Wenn du also
Werte größer als 32767 hast, musst du das sowieso anders angehen.
#638270
Lesenswert?

TobyTetzi wrote:

> "Drehzahl: XXXX U/min           Spannung: XXX Volt              "
>
> wie bekomme ich nun noch hier:             ^ ein Komma dazwischen?
>
> "Drehzahl: XXXX U/min           Spannung: X,XX Volt              "
>
> Da muß ich doch diese Funktion :
> itoa(Zahl2, string, 10);
> strcat(buf, string);
> zerlegen, nach den ersten Ziffern ein "," schreiben, und dann die
> letzten Ziffern, richtig?

Das ist eine Möglichkeit, das ',' im Nachhinein in den String
einzuschmuggeln, ja.

Eine andere Möglichkeit:
Wieviel ergibt 523 / 10?  Richtig, das macht 5
Und was ergibt 523 % 10?  Genau, das macht 23

Wenn du also zuerst die 5 ausgibst, dann ein Komma und dann
die 23, steht auf deinem Display: 5,23

(Die führenden Nullen bei der Modulo Division nicht vergessen:
  507 % 10  macht 7!  D.h. bei der Ausgabe muss zuerst 5, dann
  ein Komma, dann eine 0 und dann erst die 7 ausgegeben werden)
#638309
Lesenswert?

TobyTetzi wrote:
> Hallo Karl Heinz,
>
> ich habe schon ein C Buch (C für Mikrocontroller, von Franzis),
> allerdings ist es nicht so toll, da mir eigentlich immer die Beispiele
> genau zu meinem Problem fehlen.

Die wirst du auch in keinem Buch finden.
Programmieren lebt davon, dass man Bausteine kombinieren kann.
Bausteine können sein:
  Arithmetische Anweisungen
     kein µC kann aus einer Zeitdifferenz eine Frequenz berechnen.
     Aber es gibt die Operation 'Division'. Und wenn man jetzt
     noch weiss, dass
              f = 1 / t
     dann hat man das Problem durch Kombination von 2 'Bausteinen'
     gelöst

  Algorithmen
     Für viele Problemstellungen gibt es Standardverfahren.
     Ein gutes Buch führt einen auf spielerische Art und Weise
     in die wichtigsten und häufigsten Algorithmen ein, indem
     sie entweder besprochen oder aber als Idee skizziert und
     als Übungsaufgabe gestellt werden. Drum ist das Durcharbeiten
     von Übungsaufgaben in einem Programmierbuch auch so wichtig.

  Standardbibliotheken
     Einige (meist einfache) Algorithmen sind von so fundamentaler
     Bedeutung, dass mit dem Programmiersystem auch entsprechende
     vorgefertigte Funktionen mitgeliefert werden. Die sollte man
     kennen und mit ihnen (im Rahmen von Übungsaufgaben) auch mal
     gearbeitet haben, damit man sich an sie erinnert wenn man
     sie braucht.

Dreh und Angelpunt ist aber immer wieder eines:
Programmieren lernt man nur durch Programmieren. Ein Buch einfach
nur durchzulesen ist vergeudete Zeit. Man muss das, was man gelesen
hat auch sofort in einem Programm umsetzen, eventuell etwas abwandeln
um zu sehen, was man sonst noch mit der präsentierten Idee machen
kann. Nur so lernt man und merkt sich auch, welche Funktionen es
gibt, wie sie eingesetzt werden und welche Ideen dahinter stecken.
Dann hat man seine Bausteine im Kopf parat und kann sie abrufen
wenn man sie braucht. Das Buch braucht man dann nur noch, um Details
die man sich nicht gemerkt hat, nachschlagen zu können. Was aber nicht
heist, dass solche Detail-Nachschlagbücher (auch solche gibt es)
für den Anfang empfehlenswert sind. Ganz im Gegenteil.
#638352
Lesenswert?

Johannes M. wrote:
> Karl heinz Buchegger wrote:
>> Eine andere Möglichkeit:
>> Wieviel ergibt 523 / 10?  Richtig, das macht 5
>> Und was ergibt 523 % 10?  Genau, das macht 23
> Eher "/100" bzw. "%100", gell?

<Geräusch, das entsteht, wenn die Stirn auf der Tischplatte
aufschlägt>

Danke.
#638410
Lesenswert?

Karl heinz Buchegger wrote:
> <Geräusch, das entsteht, wenn die Stirn auf der Tischplatte
> aufschlägt>
Na, kein Grund zur Selbstverstümmelung;-) War nur, um sicherzugehen, 
dass kein unbedarfter Anfänger tatsächlich glaubt, 523 / 10 ist 5... 
Kannste ja oben ändern und meine beiden letzten Postings löschen...

Gruß

johnny.m

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren