www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik MSP430 IAR: String1 in String2 Kopieren??


Autor: XMEN (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
hallo.
weisst jemand wie ich ein String1 in einen anderen String2 kopieren 
kann?

BSP:
String1 = "  Hallo Word " muss in String2 kopiert.

danke

Autor: Bernhard (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wie wärs mit?

#include <string.h>

und dann

strcopy (string2, string1);

Autor: Christian R. (supachris)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das wäre die brutal-Methode mit massenhaft Speicherplatz-verschwendung 
durch die dazu gelinkte Library.

Wieso nicht einfach:

while(*string1 != 0)
{
*string2 = *string1;
string1++;
string2++;
}

Dazu müssen allerdings die Strings als Pointer deklariert sein, was ja 
eh sinnvoll ist:

char *string1 = {"Blabla"};
char *string2 = {"blabla"};

wichtig ist, auch den 2. String schon mit irgendwelchen zeichen zu 
definieren, damit der Compiler weiß, wieviel Platz er reservieren muss.

Autor: XMEN (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
danke
es hat geklapt.

die erste Version ist einfacher und hat funktioniert. danke euch

Autor: Bernhard (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ähm,

der Compiler übersetzt doch eh alles in Maschinencode, oder?
Und die Library is doch nur für den Compiler?
Is dann nicht alles nur die Frage welchen Compiler du verwendest? Und 
wie gut der optimiert?

Korrigier mich wenn ich mich irre.

Autor: XMEN (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
wie kann ich dann bis zu einem bestimmten zeichen kopieren?? sagen wir 
bis zum nächsten leezeichen? und im String liegen 3 leezeichen.

danke

Autor: Karl heinz Buchegger (kbucheg)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Dazu müssen allerdings die Strings als Pointer deklariert sein, was ja
> eh sinnvoll ist:
>
> char *string1 = {"Blabla"};
> char *string2 = {"blabla"};

Autsch.
genau so darfst du es auf keinen Fall machen.
Die Pointer zeigen auf konstante String Literale.
Die sind für dein Programm tabu und dürfen im Program
nicht verändert werden.

Wenn schon, dann zumindest

char *string1 = {"Blabla"};
char string2[] = {"blabla"};

Das ist ein kleiner Unterschied.

> Das wäre die brutal-Methode mit massenhaft Speicherplatz-verschwendung
> durch die dazu gelinkte Library.

Völliger Unsinn. Die str... Funktionen hast du sowieso mit,
weil sie in der C-Standardlibrary enthalten sind, die der
Compiler immer mit dazulinkt.
Und wenn dein Linker freundlich genug ist, alles was in der
Standardlibrary nicht gebraucht wird auch nicht mit ins EXE
zu übernehmen, so sind die Kosten für strcpy() auch nicht
höher als wenn du die Funktion selber schreibst. Im schlimmsten
Fall enthält dein EXE 2 strcpy(): Eines aus der Standard-Library
und eines das du selbst geschrieben hast. Also lass es.


Autor: Bernhard (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Dann von Hand, denk ich.


unsigned char i=0;
//es sei denn dein String ist länger als 254 Zeichen + '\0

while (i<Stringlänge)
{
while( string1[i] !=' ' && string[i] !='\0')
{
string2[i]=string1[i];
i++;
}
}


Geht vermutlich auch eleganter, funktioniert aber erstmal.

Autor: Karl heinz Buchegger (kbucheg)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Bernhard wrote:
> Dann von Hand, denk ich.
>
>
> unsigned char i=0;
> //es sei denn dein String ist länger als 254 Zeichen + '\0
>
> while (i<Stringlänge)
> {
> while( string1[i] !=' ' && string[i] !='\0')
> {
> string2[i]=string1[i];
> i++;
> }
> }
>
>
> Geht vermutlich auch eleganter, funktioniert aber erstmal.

Allerdings.
Die Stringlänge brauchst du gar nicht.
In C ist ein String definiert als eine Zeichenfolge,
die mit einem '\0' Zeichen aufhört.

Obiges ist schon eine sehr spezielle Kopierfunktion,
die fischt dir alle Leerzeichen aus dem String heraus
(Was ist wenn da ein Tabulator drinn ist? :-)
Alle, nicht nur die Einleitenden. Bist du sicher das
du das haben möchtest?

Auch darfst du nicht vergessen im Zielstring auch das
letzte '\0' wieder reinzustellen.
void myCopy( const char* source, char* dest )
{
  while( *source) {
    if( *source != ' ' && *source != '\t' ) {
      *dest = *source;
      dest++;
    }
    source++;
  }

  *dest= '\0';
}

Autor: Christian R. (supachris)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Also damit der GCC konstante Strings erzeugt, muss ich doch "const" vor 
die Deklaration schreiben. Ansonsten ist das ein Array am Ende, was im 
RAM liegt. Der Kompiler reserviert den Speicher und schreibt in dem Fall 
den Text rein, ans Ende hängt er eine Null. Kann man sich wunderbar im 
Debugger anschauen nachher. Wie das der IAR hält weiß ich nicht. Und der 
GCC linkt auch die StdLib nicht dazu, wenn ich das nicht explizit 
angebe.

Ich programmiere µCs nach Möglichkeit effizient, wozu brauch ich ne 
ganze Lib für so nen Pillepallekram? Schluckt nur wertvollen 
Programmspeicherplatz.
Die paar Pointer-Operationen sind doch schnell geschrieben.

Autor: Karl heinz Buchegger (kbucheg)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Also damit der GCC konstante Strings erzeugt, muss ich doch "const" vor
> die Deklaration schreiben.

Ein String Literal, wie "Dies ist ein String" ist per C Definition
konstant. Dein Programm hat kein Recht da drin irgendwelche
Zeichen zu verändern.

Autor: Karl heinz Buchegger (kbucheg)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Ansonsten ist das ein Array am Ende, was im
> RAM liegt.

Dann probier mal folgendes:
#include <avr/io.h>

char* Text1 = "Ein Text";
char* Text2 = "Ein Text";

int main()
{
  Text1[2] = 'b';
  Text2[3] = 'a';

}

Dann kompilierst du das mal mit -Os
und anschliessend machst du:
  * Du vergleichst mal die Pointerinhalte von Text1 und Text2
  * Du lääst dir mal *Text1 und *Text2 ausgeben

Es lohnt sich!



Autor: Karl heinz Buchegger (kbucheg)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Und der
> GCC linkt auch die StdLib nicht dazu, wenn ich das nicht explizit
> angebe.

Ach. Wie gibst du denn explizit an, dass du die StdLib
mit dazugelinkt haben willst? Da bin ich jetzt aber
neugierig.

> Ich programmiere µCs nach Möglichkeit effizient, wozu brauch ich ne
> ganze Lib für so nen Pillepallekram?

Vielleicht deshalb, weil in der Standard Library das komplette
Runtime System von C enthalten ist? Das braucht nämlich
dein Program um zu funktionieren. Überraschung: Die
Programmausführung beginnt auf Assembler Ebene nämlich
nicht bei main(). Da passiert vorher schon was. Was denkst
du wo der Code herkommt? Richtig der kommt aus der
Standard Library.

> Die paar Pointer-Operationen sind doch schnell geschrieben.

Klar. Aber wozu das ganze nochmal schrieben, wenn ichs
schon fertig da habe.

Das hier:
#include <avr/io.h>

char Text1[] = { "Ein Text1" };
char Text2[] = { "Ein Text2" };

void mystrcpy( char* dest, char* src )
{
  while( *src )
    *dest++ = *src++;
  *dest = '\0';
}

int main()
{
  mystrcpy( Text1, Text2 );
}

verbraucht bei -Os  208 Bytes

Das hier
#include <avr/io.h>
#include <string.h>

char Text1[] = { "Ein Text1" };
char Text2[] = { "Ein Text2" };

int main()
{
  strcpy( Text1, Text2 );
}
verbraucht 202 Bytes.

Von wegen: Selber schreiben ist kürzer.
Du solltest Dinge nicht raten, sondern ausprobieren.


Autor: Michael (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Ich programmiere µCs nach Möglichkeit effizient, wozu brauch ich ne
> ganze Lib für so nen Pillepallekram? Schluckt nur wertvollen
> Programmspeicherplatz.

Das Schöne an LIBs ist ja, daß nur die Routinen gebunden werden, die man 
tatsächlich braucht: nix mit "Schluckt nur wertvollen 
Programmspeicherplatz."

Es gibt auch noch strncpy(), ...

Autor: Karl heinz Buchegger (kbucheg)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Ansonsten ist das ein Array am Ende, was im
> RAM liegt.

Das hängt damit zusammen, dass der AVR eine Harvard
Architektur hat und SRAM und Flash anders adressiert
werden. Bei Prozessoren wo das nicht so ist, zb Z80 + EPROM
kann der Compiler String Literale auch ins ROM legen.

char* Text = "Ein Text";

Das String Literal "Ein Text" liegt im ROM. Im RAM wird der
Speicher für den Pointer angelegt und mit der Adresse im ROM
initialisiert.

const char* Text = "Ein Text";

Ist identisch zu obigen. Eigentlich ist das sogar die richtige
Schreibweise. Das der Compiler das Vorhergehende überhaupt
akzeptiert hat historische Ursachen: Eigentlich ist die
erste Version falsch. Man wollte aber aufwärtskompatibel
bleiben. Daher hat man (ausnahmsweise) erlaubt, dass ein
const char* an einen char* zugewiesen werden kann, auch
wenn das streng genommen falsch ist.

const char* const Text = "Ein Text";

Hier liegt sowohl das String Literal selbst, als auch
der Pointer im ROM.

Auf einem AVR kann man das aber so nicht machen, da ja
Flash und SRAM anders adressiert werden und es für den
Prozessor nicht möglich ist, aus dem Pointerwert zu ermitteln
ob das jetzt ein Zugriff aufs Flash oder aufs SRAM ist.
Also geht man den pragmtischen Weg: Alles kommt ins SRAM.

Das ändert aber nichts daran, was der C Standard dazu zu
sagen hat. Und der sagt lapidar: "String Literale sind konstant.
Ihr Datentyp ist const char*"

Autor: Christian R. (supachris)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hast Recht, hatte es falsch in Erinnerung. Ich hab auch immer die 
Array-Deklaration benutzt.  Dann aber über Pointer auf das Array 
zugegriffen, und vorher die Adresse geholt. Hab´s verwechselt, weil ich 
die kontanten Ausgabestrings immer über die besagte Deklarations mit 
const ins Flash geschoben hab.

Zur Stdlib: Dann hab ich das wohl auch missverstanden. Ich dachte du 
meinst die lib, in der halt diese ganzen String-Sachen drin sind. Sollte 
wohl genauer lesen ;)

Ich wollte für mein Projekt mal diese String-Funktionen benutzen (GCC). 
Als ich sie zugelinkt hatte, war das Programm gleich ziemlich 
aufgeblasen, dann hab ich mir das Vergleichen der Strings selber 
geschrieben, hat viel weniger gebraucht. Vielleicht muss man dem GCC 
erst noch irgendwas sagen, dass der da sinnvoller mit umgeht? Ich hatte 
nur das strcmp benutzt und der hatte da soweit ich mich erinnere knapp 
2k an Programmspeicher mehr.

Eventuell gibts da Unterschiede zwischen dem AVR und dem MSP430 
Compiler. Ich arbeite nur mit den MSPs.

Autor: Falk (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Karl heinz Buchegger

> Also geht man den pragmtischen Weg: Alles kommt ins SRAM.

Gibt es denn auf dem AVR in C eine Möglichkeit, Konstanten in den Flash 
zu verlegen?

MFG
Falk

Autor: Karl heinz Buchegger (kbucheg)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Falk wrote:
> @Karl heinz Buchegger
>
>> Also geht man den pragmtischen Weg: Alles kommt ins SRAM.
>
> Gibt es denn auf dem AVR in C eine Möglichkeit, Konstanten in den Flash
> zu verlegen?
>

Guckst du hier

http://www.mikrocontroller.net/articles/AVR-GCC-Tu...

Autor: Karl heinz Buchegger (kbucheg)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Eventuell gibts da Unterschiede zwischen dem AVR und dem MSP430
> Compiler. Ich arbeite nur mit den MSPs.

Das könnte sein.
Ich benutze den gcc für AVR.

Ob und wie der Linker diese Optimierung machen kann, hängt
beim gcc auch davon ab, wie diese Libraries aufgebaut
werden. In der AVR Version kann er es offensichtlich.


Autor: XMEN (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>void myCopy( const char* source, char* dest )
>{
>  while( *source) {
>    if( *source != ' ' && *source != '\t' ) {
>      *dest = *source;
>      dest++;
>    }
>    source++;
>  }
>
>  *dest= '\0';
>}


hilft mir die obengenannt funk? sodass ich den string in 4 felder 
verteile.

BSP:
String = " hallo wie gehts dir"

String1 = "hallo"
String2 = "wie"
String3 = "gehts"
string4 = "dir"

Autor: Karl heinz Buchegger (kbucheg)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Nein.

Denk logisch. Schau dir die Schnittstelle der Funktion
an. Da geht 1 String rein (source) und ein String raus (dest).
Wie soll die Funktion also den String in 4 Felder
unterteilen?

Schau dir die Funktionen strstr() und strtok() an.
Die helfen dir bei deinem Problem.

Autor: XMEN (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ich habe so gemacht ok:
char String1[4][50];
dann eine for schleife genommen dass es zeichenweise kopiert und wenn 
leerzeichen kommt dann soll er auf nächsten String kopieren usw.
es hat funktioniert.
danke

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.