hello, kann man im Keil aus einem Array einen String erzeugen? Das Problem: erst mein Programm ermittelt, aus wie vielen Elementen dieses Array besteht. Das Array kann so aussehen: [0] = 'x'; Oder so: [0] = 'a'; [1] = 'b'; Oder auch mit mehreren Elementen. Wie viele es sind, hängt davon ab, wie viele ich von außen (über serielle Schnittstelle) bekomme. Es soll aber immer ein String draus werden. Geht das? EDIT: Vielleicht sollte ich noch einen Pseudocode dazuschreiben, damit klar ist, was ich meine: char sText[]; sText=""; sText+="a"; sText+="b"; sText+="c"; Am Schluss soll in sText stehen: "abc"
> kann man im Keil aus einem Array einen String erzeugen?
Ein String an sich ist in C bereits ein Array aus char :-o
Also wirst du nur sowas wie strcpy() oder strncpy() oder memcpy()
brauchen...
Willst du den String ausgeben? Auf ein Display oder so? Oder an den PC schicken?
> Ein String an sich ist in C bereits ein Array aus char :-o nicht ganz, ein string ist immer um ein element grösser als ein reines char array, da der abschluss-character (0, '\0') noch mit gespeichert werden muss. char string[10]; string[0..8] ==> zeichen string[9] = 0 Latürnich kann die null an jeder beliebigen stelle im array stehen, das Beispiel zeigt nur den maximalfall. > kann man im Keil aus einem Array einen String erzeugen? Ist eigentlich nur std:C Ist das Array voll, müsstest du einen memcpy(array, neuesArray, len); neuesArray[len]=0; machen, dabei muss neuesArray um eins grösser sein als array. Danach kannst du mit den str-funktionen arbeiten, da die alle auf die Abschluss-0 reagieren. --- Anmerkung: Ich bin in meinen Projekten schon lange auf Strings anstelle irgendwelcher arrays und Indizes ausgewichen, da mit der Definition, dass ein String immer mit 0 abschliesst, einiges sehr viel einfacher wird. Z.B. übergibt man nur den Stringpointer, und alles rennt. Lediglich bei einem LineEdit sollte man sich die Cursorposition merken und temporär einen len :-) VG, /th.
Lothar Miller schrieb: >> kann man im Keil aus einem Array einen String erzeugen? > Ein String an sich ist in C bereits ein Array aus char :-o > Und zur Erinnerung : das letzte Element ist ein Null Character \0. Daran wird die Länge erkannt.
Nachtrag (verdammt, warum geht hier kein Edit wenn der Beitrag nicht unten steht??) > Also wirst du nur sowas wie strcpy() oder strncpy() oder memcpy() > brauchen... Diese funktionen haut dir - wenn du Glück hast - dein OS um die Ohren (mit Ausnahme von vllt. memcpy), da sie über die Arraylänge hinaus bis zum Crash oder der nächsten NULL arbeiten würden. VG, /th.
> Diese funktionen haut dir - wenn du Glück hast - dein OS um die Ohren Für und gegen solche Fälle hilft i.A. die Funktion der Funktion vor deren Verwendung auf Eignung zu überprüfen. > Diese funktionen haut dir - wenn du Glück hast - dein OS um die Ohren Sieh mal nach, was strncpy() macht. Die ist mindestens genausogut wie memcpy()...
Lothar Miller schrieb: >> Diese funktionen haut dir - wenn du Glück hast - dein OS um die Ohren > Sieh mal nach, was strncpy() macht. > Die ist mindestens genausogut wie memcpy()... Nicht ganz ... strcpy wird "nicht" funktionieren, wenn der String nicht mit NULL abgeschlossen ist. strcpy sollte in etwa sein: memcpy(dest, src, strlen(src)); und genau da liegt die Krux: strlen kann keine sinnvolle string Länge für ein nicht NULL-terminiertes Array zurückliefern, also kopiert dir der oberhalb des dest Speichers alles mögliche über und crashed (wenn du Glück hast) irgendwann.
Random ... schrieb: > Lothar Miller schrieb: >>> Diese funktionen haut dir - wenn du Glück hast - dein OS um die Ohren >> Sieh mal nach, was strncpy() macht. >> Die ist mindestens genausogut wie memcpy()... > > Nicht ganz ... strcpy wird "nicht" funktionieren, genau lesen. Lothar schrub: strncpy ... mit einem n in der Mitte > strcpy sollte in etwa sein: > > memcpy(dest, src, strlen(src)); recht weit her ist es aber mit deinen C Kenntnissen auch nicht :-)
> genau lesen. > Lothar schrub: strncpy ... mit einem n in der Mitte ok, sry, überlesen. Dann pfeift's einem nicht in falschen Speicher (vorausgesetzt man gibt ein korrektes "n" an), aber es wird immer das gesamte Array kopiert. >> memcpy(dest, src, strlen(src)); > recht weit her ist es aber mit deinen C Kenntnissen auch nicht :-) Danke für die Blumen! Dafür bist du ja auch Mod und ich nicht :-) Wo liegt in der Funktionsweise der Unterschied? ok, hab was vergessen, aber es ging nur um eine Illustration des Problems, nicht um die Bereitstellung einer Lösung: dest[len] = 0; --- > genau lesen. > Lothar schrub: strncpy ... mit einem n in der Mitte recht weit her ist es aber mit deinen Deutsch Kenntnissen auch nicht :-)
Random ... schrieb: >> genau lesen. >> Lothar schrub: strncpy ... mit einem n in der Mitte > > ok, sry, überlesen. Dann pfeift's einem nicht in falschen Speicher > (vorausgesetzt man gibt ein korrektes "n" an), aber es wird immer das > gesamte Array kopiert. Nicht ganz. Es wird der String vollständig kopiert oder der Teil, der noch in die Destination hineinpasst. Je nachdem was zutrifft. Das einzig unangenehme bei strncpy ist die Tatsache, dass im 2-ten Fall der String kein String mehr ist. strncpy fügt bei Überlaufen der Destination kein \0 an. >>> memcpy(dest, src, strlen(src)); >> recht weit her ist es aber mit deinen C Kenntnissen auch nicht :-) > Danke für die Blumen! Dafür bist du ja auch Mod und ich nicht :-) > > Wo liegt in der Funktionsweise der Unterschied? Dass deine memcpy Variante die \0 nicht mitkopiert. Wenn schon, dann entspricht memcpy(dest, src, strlen(src)+1); einem strcpy. (Beliebter Fehler: wenn ein strlen benutzt wird um damit irgendetwas zu steuern, braucht man praktisch immer strlen(x)+1) Wer allerdings strcpy mit memcpy implementiert, sollte gleich erschlagen werden void myStrCpy( char *dest, const chat* src ) { while( *src ) *dest++ = *src++; *dest = '\0'; } >> Lothar schrub: strncpy ... mit einem n in der Mitte > recht weit her ist es aber mit deinen Deutsch Kenntnissen auch nicht :-) :-) Touche
Hab hier kaum was verstanden. Aber ich glaube, ihr habt mich sowieso nicht verstanden, was ich versuche. Liegt aber sicher an mir. Habe mich sicher falsch ausgedrückt. Weiterer Versuch :) Ich bekomme über die Serielle z. B.: 'a' 'b' 'c' '\n' 'd' 'e' 'f' 'g' '\n' 'h' '\n' Die Zeichen landen in einem Array. Jetzt habe ich versucht, die Zeichen einzeln auszulesen und bei jedem \n einen String aus den vorhergehenden Zeichen zu machen. Also: 'a' 'b' 'c' '\n' => "abc" 'd' 'e' 'f' 'g' '\n' => "defg" 'h' => "h" Ich würde das gerne in einer Schleife machen:
1 | char aChar[16]; |
2 | // Testdaten (simuliert Daten von Seriellen):
|
3 | aChar[0]='a'; |
4 | aChar[1]='b'; |
5 | aChar[2]='c'; |
6 | aChar[3]='\n'; |
7 | aChar[4]='d'; |
8 | aChar[5]='e'; |
9 | aChar[6]='f'; |
10 | aChar[7]='g'; |
11 | aChar[8]='\n'; |
12 | aChar[9]='h'; |
13 | aChar[10]='\n'; |
14 | // Array durchlaufen:
|
15 | char iI=0; |
16 | for(;iI<sizeof(aChar);++iI) |
17 | {
|
18 | if(aChar[iI]=='\n') |
19 | {
|
20 | // jetzt aus den vorhergehenden Zeichen den String erzeugen.?.?.?
|
21 | }
|
22 | }
|
Heinz B. schrieb: > for(;iI<sizeof(aChar);++iI) > { > if(aChar[iI]=='\n') > { > // jetzt aus den vorhergehenden Zeichen den String erzeugen.?.?.? Wo erzeugst du den String? In welchem Array? > } > } unsigned char iI=0; unsigned char iJ; char EinzelString[10]; // das nimmt einen einzelnen String auf iJ = 0; for(;iI<sizeof(aChar);++iI) { if(aChar[iI]=='\n') { EinzelString[iJ] = '\0'; // jetzt ist es ein String. Mach was damit printf( "%s", EinzelString ); iJ = 0; } else EinzelString[iJ++] = aChar[iI]; }
>> Wo erzeugst du den String? Das ist ja mein Problem, das ich habe. Ich erzeuge den noch nirgends, weil ich nicht weiß, wie ich das machen soll. >> char EinzelString[10]; // das nimmt einen einzelnen String auf Ein Array mit einer festen Länge zu definieren würde ich gerne vermeiden, weil die Strings immer unterschiedlich lang sind.
Heinz B. schrieb: >>> char EinzelString[10]; // das nimmt einen einzelnen String auf > Ein Array mit einer festen Länge zu definieren würde ich gerne > vermeiden, weil die Strings immer unterschiedlich lang sind. Dann wirds allerdings kompliziert :-) Wie "gut Freund" bist du mit malloc und free? Im Ernst. Auf einem µC: lege eine Maximalgröße fest und arbeite damit. Ist einfacher und auch weniger fehlerträchtig als eine dynamische Verwaltung. Was passiert den mit den Einzelstrings?
>> Wie "gut Freund" bist du mit malloc und free? Oh ... du weißt ja, dass ich mich nicht gut damit auskenne ;) Aber könntest du mir bitte trotzdem mal ein Beispiel zeigen? >> Was passiert den mit den Einzelstrings? Keine Ahnung. Vielleicht mache ich es dann auch gar nicht mit Strings. Aber ich würde gerne wissen, wie es geht.
Heinz B. schrieb: >>> Wie "gut Freund" bist du mit malloc und free? > Oh ... du weißt ja, dass ich mich nicht gut damit auskenne ;) > > Aber könntest du mir bitte trotzdem mal ein Beispiel zeigen? Ehrlich? Das willst du nicht wirklich :-) OK
1 | unsigned char iI=0; |
2 | unsigned char iJ; |
3 | char* EinzelString = NULL; // das nimmt einen einzelnen String auf |
4 | |
5 | iJ = 0; |
6 | for(;iI<sizeof(aChar);++iI) |
7 | {
|
8 | if(aChar[iI]=='\n') |
9 | {
|
10 | EinzelString[iJ] = '\0'; |
11 | // jetzt ist es ein String. Mach was damit
|
12 | printf( "%s", EinzelString ); |
13 | free( Einzelstring ); |
14 | EinzelString = NULL; |
15 | iJ = 0; |
16 | }
|
17 | else { |
18 | EinzelString = realloc( iJ + 2 ); // Platz für den \0 auch gleich mitnehmen |
19 | if( !Einzelstring ) |
20 | break; |
21 | EinzelString[iJ++] = aChar[iI]; |
22 | }
|
23 | }
|
Aber ich warne dich eindringlich. Das öffnet auf einem µC mit seinem sehr begrenzten Speicher die Büchse der Pandora. Speicherfragmentierung kann dir da ganz schnell einen Strich durch die Rechnung machen und im Endeffekt ist die maximale Länge der Strings die du gerade noch bearbeiten kannst dann kleiner als wenn du gleich eine statische Allokierung mit einer Maximallänge gemacht hättest. >>> Was passiert den mit den Einzelstrings? > Keine Ahnung. Vielleicht mache ich es dann auch gar nicht mit Strings. Das wäre aber gut zu wissen. Unter Umständen muss man nämlich die Teilstrings gar nicht aus dem kompletten rauskopieren. Eine Abfolge von Zeichen, die mit einem \0 beendet wird, ist in C ein String. Wenn man also in aChar die \0 korrekt einsetzt und einen Pointer auf den Anfang der Zeichen hat, kann man den Pointer wunderbar an eine stringverarbeitende Funktion übergeben.
Aber jetzt kommts mir erst :-) Du bist doch der Heinz B. mit dem Ringbuffer? Da macht man das dann allerdings anders (am Prinzip der statischen Allokierung würde ich aber trotzdem festhalten) Du brauchst eine Funktion getCharacter(), die dir das nächste Zeichen aus dem Ringbuffer holt. Wenn keines verfügbar ist, muss man entscheiden: soll die Funktion warten oder soll sie mitteilen, dass nichts da ist. Ich nehme mal den einfachsten Fall: sie wartet
1 | ...
|
2 | |
3 | char NextString[20]; |
4 | unsigned char i; |
5 | char c; |
6 | |
7 | i = 0; |
8 | c = getCharacter(); |
9 | while( c != '\n' ) { |
10 | NextString[i++] = c; |
11 | c = getCharacter(); |
12 | }
|
13 | NextString[i] = '\0'; |
14 | |
15 | // jetzt hast du in NextString den nächsten komplett empfangenen String
|
16 | // der mit einem \n abgeschlossen wurde
|
17 | |
18 | printf( "%s", NextString ); |
19 | |
20 | ...
|
Fehlerbehandlung, damit NextString nicht überlaufen wird, wäre noch sinnvoll :-)
Schaut wirklich kompliziert aus, das Programm. Wenn ich das jetzt richtig verstanden haben, ist das hier ein korrekter String: char sText[255]; sText[0]='a'; sText[1]='b'; sText[2]='\0'; Und die restlichen leeren Arrayelemente stören dann nicht irgendwie? Kann man dann ganz normal mit den String-Funktionen arbeiten? EDIT: ja genau, ich bin der "ringbuffer-heinz" lach
Heinz B. schrieb: > Schaut wirklich kompliziert aus, das Programm. > > Wenn ich das jetzt richtig verstanden haben, ist das hier ein korrekter > String: > > char sText[255]; > sText[0]='a'; > sText[1]='b'; > sText[2]='\0'; > > Und die restlichen leeren Arrayelemente stören dann nicht irgendwie? > Kann man dann ganz normal mit den String-Funktionen arbeiten? Du solltest dir wirklich Literatur zulegen. In der Zwischenzeit kannst du das als Einführung nehmen http://www.mikrocontroller.net/articles/FAQ#Wie_funktioniert_String-Verarbeitung_in_C.3F
Wunderbar. Womit meine Frage beantwortet wäre. Danke :) P. S. Literatur habe ich. Ein Büchlein. Leider ein wenig oberflächlich und ziemlich alt. Aber grundsätzlich für Anfänger ganz ok, glaube ich.
Heinz B. schrieb: > Literatur habe ich. Ein Büchlein. Leider ein wenig oberflächlich > und ziemlich alt. Aber grundsätzlich für Anfänger ganz ok, glaube ich. Kauf dir irgendeine Ausgabe des K&R, das ist das Standardwerk schlechthin. (Kernighan & Ritchie, Programmieren in C)
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.