Forum: Compiler & IDEs Insert String für "C" ohne malloc


von Martin M. (ats3788)


Lesenswert?

Hallo
Wenn man in C einen string in einen anderen einsetzen möchte
findet man im Netz ein haufen insert Befehle mit malloc.

Nur sind die für µC suboptimal.

Deswegen meine Frage. Gibt es einen insert Befehl ohne malloc

: Verschoben durch User
von Sebastian V. (sebi_s)


Lesenswert?

Was heißt einsetzen? Wenn du strings kopieren möchtest benutzt du am 
Besten strcpy oder wenn du aneinander hängen möchtest strcat. 
Funktioniert beides ohne malloc. Natürlich sollte am Ziel dann auch 
genug Platz für den kompletten String sein.

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

Martin Michael schrieb:
> Wenn man in C einen string in einen anderen einsetzen möchte
> findet man im Netz ein haufen insert Befehle mit malloc.

Was heisst "einsetzen"? Soll der an beliebiger Stelle eingefügt werden, 
z.B. so:

Vorher:

   "Hallt"

Jetzt ein insert zwischen die beiden "l" von "lo We":

   "Hallo Welt"

> Deswegen meine Frage. Gibt es einen insert Befehl ohne malloc

Solange der Ziel-Buffer genügend Zeichen aufnehmen kann, brauchst Du 
keinen malloc().

von Karl H. (kbuchegg)


Lesenswert?

Martin Michael schrieb:
> Hallo
> Wenn man in C einen string in einen anderen einsetzen möchte
> findet man im Netz ein haufen insert Befehle mit malloc.
>
> Nur sind die für µC suboptimal.
>
> Deswegen meine Frage. Gibt es einen insert Befehl ohne malloc

Was spricht dagegen, sich mittels strcat, strcpy (strncpy), memcpy 
selbst was zusammenzubauen, bzw. sich selbst eine Abart von strcpy zu 
bauen, die damit sicher klar kommt, wenn sich source und destination 
überlappen?

Das Problem bei einem insert ist, dass der String dadurch länger wird. 
Wodurch das Zielarray gross genug sein muss. Deshalb wird hier gerne mit 
malloc gearbeitet, wie auch im Rest der String-Bearbeitung auf 
Desktopsystemen. Das man das auf einem µC mit wenig Speicher tunlichst 
nicht macht ist schon klar. Dann muss man eben anders an die Sache 
rangehen.
So ein insert ist ja prinzipiell nicht so schwer.
An der Stelle, an der der andere String eingesetzt werden soll muss eine 
Lücke geschaffen werden, in dem der Rest des Strings hinter der 
Einfügeposition entsprechend 'nach hinten' kopiert wird. In die so 
entstandene Lücke wird dann der andere String einkopiert. Wobei man 
natürlich tunlichst auf das String-typische Abschlussbyte \0 achtet, 
dass einem dieses keinen Strich durch die Rechnung macht.

Das ist die Variante, die 'in-place' arbeitet. Will man eine Variante, 
die einen neuen, dann eben zusammengesetzten String, hervorbringt, dann 
ist die Sache noch einfacher. Mittels strncpy bzw. strcat bzw. strncat 
werden die Einzelteile im Zielarray aneinander gehängt.

Versuch es doch mal. Dabei lernst du viel mehr, als duch Copy&Paste 
Programmierung. In der Zeit, in der du im Web nach einer entsprechenden 
Routine gesucht hast, hättest du dich schon längst darüber schlau machen 
können, wie String Verarbeitung in C eigentlich funktioniert, welche 
Funktionen du vorrätig hast und ein paar Versuche machen können, wie man 
durch Kombination der Funktionen etwas gewünschtes erzielen kann, 
nachdem man sich einen Plan gemacht hat, welche Operationen in welcher 
Reihenfolge eigentlich zum gewünschten Ergebnis führen. Da fängt 
programmieren an und nicht beim Suchen im Web nach fertigen Funktionen. 
Zumindest nicht bei Funktionen auf diesem 'Schwierigkeitslevel'.

: Bearbeitet durch User
von Max H. (hartl192)


Lesenswert?

Martin Michael schrieb:
> Gibt es einen insert Befehl ohne malloc
Wenn string, in den eingesetzt wird, nur genauso lange ist wie es 
Zeichen + Nullterminierung hat, ist das ohne malloc gar nicht möglich, 
wenn er lange genug ist, dann könnte man es so lösen:
1
  char a[20]="12345";
2
  char b[]="ABCDE";
3
  int pos = 2;
4
5
  memcpy(a + strlen(b) + pos, a + pos, strlen(a) - pos + 1);
6
  memcpy(a + pos, b, strlen(b));
7
8
  printf("%s\n", a);  // Prints "12ABCDE345

: Bearbeitet durch User
von Karl H. (kbuchegg)


Lesenswert?

Max H. schrieb:

>   memcpy(a+strlen(b)+pos, a+pos, strlen(a)-pos);

memmove

memcpy muss nicht mit overlapping Bereichen klar kommen.
In deinem Beispiel entsteht das, wenn
1
  char b[]="AB";

Dann wird in a der Teil "345" zum Teil auf sich selber kopiert. Je 
nachdem ob memcpy vorne oder hinten mit dem kopieren anfängt, entsteht 
dann ein falsches Ergebnis.

: Bearbeitet durch User
von Martin M. (ats3788)


Lesenswert?

Danke für die antworten.
Ja ich habe darüber nachgedacht und strcpy und strcat das langt
für die benötigte Stringbearbeitung. Mann muss nur vorher besser planen, 
aber mit euren Antworten lernt man etwas dazu.

von Pandur S. (jetztnicht)


Lesenswert?

Wir wissen leider nicht um welchen Controller es geht. Bei groesseren, 
32 bit controllern, hat man mehr Rechenleistung zum Verpuffen. Bei 
Kleinen, zB AVR, haelt man Strings natuerlich statisch, mit fester 
Laenge. Da die Strings ja meist kurz sind, lohnen sich String libraries 
nicht. Im Wesentlich geht's darum in einer FOR loop zu kopieren. Dann 
macht man das eben so. Und natuerlich verwendet man keine 
nullterminierten strings, sondern haelt die Lange in einer Variablen, zB 
dem 0-ten byte des arrays.

Bei einem LCD beschreibt man am Besten eine ganze Zeile und nicht Teile 
davon. Deswegen ist ein String auch statisch mit fester Laenge.

: Bearbeitet durch User
von Karl H. (kbuchegg)


Lesenswert?

Jetzt Nicht schrieb:

Zum Rest hab ich keine Einwände.
Aber das

> Und natuerlich verwendet man keine
> nullterminierten strings, sondern haelt die Lange in einer Variablen, zB
> dem 0-ten byte des arrays.

ist Unsinn.

von Bronco (Gast)


Lesenswert?

Karl Heinz schrieb:
> Jetzt Nicht schrieb:
>
> Zum Rest hab ich keine Einwände.
> Aber das
>
>> Und natuerlich verwendet man keine
>> nullterminierten strings, sondern haelt die Lange in einer Variablen, zB
>> dem 0-ten byte des arrays.
>
> ist Unsinn.

Nein, das ist Pascal.

von Markus F. (mfro)


Lesenswert?

Martin Michael schrieb:
> Gibt es einen insert Befehl ohne malloc

Klar. Der heißt sprintf().

von Läubi .. (laeubi) Benutzerseite


Lesenswert?

DIe Frage ist sowieso ob man da überhaupt was ein bzw. ersetzen muss.
Normalerweise existiert so ein String ja nicht einfach so im Speicher 
und gammelt da vor sich hin, sondern wird z.B. auf ein Terminal o. ä. 
ausgegeben, man kann dieses "einfügen" also auch ganz einfach an der 
Stelle der Ausgabe machen den ob ich "ABCDEFGHIJKLM" als String sende 
oder erst ein "A" dann "BCDEFGHIJ" und am Schluss "KLM" ist für das 
Ergebnis in den allermeisten Fällen völlig egal.

von Rolf Magnus (Gast)


Lesenswert?

Bronco schrieb:
>>> Und natuerlich verwendet man keine
>>> nullterminierten strings, sondern haelt die Lange in einer Variablen, zB
>>> dem 0-ten byte des arrays.
>>
>> ist Unsinn.
>
> Nein, das ist Pascal.

Seit wann ist Pascal denn Teil von C?

von Joachim B. (jar)


Lesenswert?

Läubi .. schrieb:
> DIe Frage ist sowieso ob man da überhaupt was ein bzw. ersetzen muss.

guter Einwand.

Ich rechne gerne bei ADC Werden mit Ints statt mit float und weil ich 
trotzdem gerne ein Komma einsetze habe ich mir eine insert_char gebaut 
die dann den String ans LCD schickt.

Klar muss ich kein Komma in den String einsetzen aber es ist für mich 
einfacher bei Bedarf den String zum LCD zu schicken als bei der LCD 
Ausgabe abzuzählen wann das Komma kommen muss, ausserdem kann ich den 
String auch in ein LCD Schattenarray in den Hintergrund schreiben um bei 
Bedarf die LCD Anzeige umschalten zu können, z.B. bei Menüwechsel oder 
LCD refresh

von Amateur (Gast)


Lesenswert?

Wenn Du Dich um alles selber kümmerst, brauchst Du kein malloc.

Dazu musst Du allerdings alle "Basis"-Strings lang genug deklarieren.
An dieser Stelle ist aber meist der Hund begraben.
Vor allem, wenn Du keine Ahnung hast, wieviel Platz Du tatsächlich 
brauchst.

malloc ist halt nicht nur ein Speicher- und Zeitfresser.

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.