Insert String für "C" ohne malloc

Moderator Persönliche Seite #3976310
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().
#3976314
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'.
#3976337
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
#3976343
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.
#3979171
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.
Persönliche Seite #4005067
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.
#4005098
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
Gast #4005121
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.

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