hallo. weisst jemand wie ich ein String1 in einen anderen String2 kopieren kann? BSP: String1 = " Hallo Word " muss in String2 kopiert. danke
Wie wärs mit? #include <string.h> und dann strcopy (string2, string1);
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.
danke es hat geklapt. die erste Version ist einfacher und hat funktioniert. danke euch
Ä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.
wie kann ich dann bis zu einem bestimmten zeichen kopieren?? sagen wir bis zum nächsten leezeichen? und im String liegen 3 leezeichen. danke
> 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.
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.
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.
1 | void myCopy( const char* source, char* dest ) |
2 | {
|
3 | while( *source) { |
4 | if( *source != ' ' && *source != '\t' ) { |
5 | *dest = *source; |
6 | dest++; |
7 | }
|
8 | source++; |
9 | }
|
10 | |
11 | *dest= '\0'; |
12 | }
|
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.
> 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.
> Ansonsten ist das ein Array am Ende, was im > RAM liegt. Dann probier mal folgendes:
1 | #include <avr/io.h> |
2 | |
3 | char* Text1 = "Ein Text"; |
4 | char* Text2 = "Ein Text"; |
5 | |
6 | int main() |
7 | {
|
8 | Text1[2] = 'b'; |
9 | Text2[3] = 'a'; |
10 | |
11 | }
|
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!
> 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:
1 | #include <avr/io.h> |
2 | |
3 | char Text1[] = { "Ein Text1" }; |
4 | char Text2[] = { "Ein Text2" }; |
5 | |
6 | void mystrcpy( char* dest, char* src ) |
7 | {
|
8 | while( *src ) |
9 | *dest++ = *src++; |
10 | *dest = '\0'; |
11 | }
|
12 | |
13 | int main() |
14 | {
|
15 | mystrcpy( Text1, Text2 ); |
16 | }
|
verbraucht bei -Os 208 Bytes Das hier
1 | #include <avr/io.h> |
2 | #include <string.h> |
3 | |
4 | char Text1[] = { "Ein Text1" }; |
5 | char Text2[] = { "Ein Text2" }; |
6 | |
7 | int main() |
8 | {
|
9 | strcpy( Text1, Text2 ); |
10 | }
|
verbraucht 202 Bytes. Von wegen: Selber schreiben ist kürzer. Du solltest Dinge nicht raten, sondern ausprobieren.
> 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(), ...
> 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*"
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.
@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
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-Tutorial#Vereinfachung_f.C3.BCr_Zeichenketten_.28Strings.29_im_Flash
> 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.
>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"
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.
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
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.