Sorry Leut,
aber warscheinlich seh ich schon den Wald vor lauter Bäumen nicht. Ich
arbeite mit avr-libc und procyon Bibs und bin auf der Suche nach der
"mid-Funktion" (also eben einen Teil aus einem String herausschneiden).
Das wird es doch bestimmt schon geben, oder? Könnte mir mal bitte jemand
den Funktionsnamen verraten.
Danke
Gibt's in der Form in C nicht. Es kommt darauf an, was damit passieren
soll. Wenn Du den Originalstring nicht mehr brauchst:
char String[] = "Die Mitte rausschneiden";
// Neuer String soll "Mitte" lauten!
String[9] = 0; // Leerzeichen hinter "Mitte" mit Stringende
überschreiben
char * Mittenstring = String + 4; // Zeigt auf das M
printf(Mittenstring); // gibt "Mitte" aus.
Wenn Du ihn noch brauchst, kopierst Du stattdessen mit strncpy:
strncpy(Zielstring, String + 4, 5);
D.h. also die Zeichenkette, die vier Zeichen hinter dem Stringanfang
beginnt (also beim M) fünf Zeichen lang kopieren. Der String wird dann
automatisch mit einer Null abgeschlossen.
Kannst Du mal beschreiben, was eine mid-Funktion macht ?
In C wird gerne mit Pointern gearbeitet.
Wenn man also aus einem Text den Rest ab dem 5. Zeichen ausgeben will,
schreibt man einfach
printf("%s", text+5);
Nur wenn man was verändern und das Original behalten will, muß man
wirklich kopieren, z.B. mit strncpy().
Peter
"Der String wird dann automatisch mit einer Null abgeschlossen."
Dieses naheliegende Missverständnis bei strncpy() dürfte für einen Teil
der berüchtigten buffer overflows verantwortlich sein.
Nein. So ist es eben nicht. Doku zu strncpy lesen.
Wow, nicht schlecht, das hatte ich wirklich vergessen. Bei strcpy wird
also die Null mitkopiert, bei strncpy aber nur, wenn auch das Ende des
Ursprungsstrings erreicht wird. Der einzige Unterschied zu memcpy ist
also, daß bei letzterem hinter dem Ursprungsstringende der Rest mit
Nullen aufgefüllt wird (was in 99% der Fälle niemanden interessiert).
Wer hat sich das so ausgedacht?
Jetzt muß ich wirklich nochmal überprüfen, ob alle Benutzungen dadurch
gesichert sind, daß von der Allokation noch die Nullen übrig sind. Also
vielen Dank!
> Der einzige Unterschied zu memcpy ist> also, daß bei letzterem hinter dem Ursprungsstringende der Rest> mit Nullen aufgefüllt wird (was in 99% der Fälle niemanden> interessiert).
Äh, nein, das kann man so nicht sagen.
memcpy interessiert sich überhaupt nicht für den Inhalt
des Speichers. memcpy() kopiert einfach nur Speicherbereiche,
was auch immer da drinn enthalten ist. Da wird nichts
aufgefüllt. Wenn im Quellstring zufällig nach dem ersten '\0'
Byte noch weitere '\0' Bytes kommen, dann werden die selbst-
verständlich mitkopiert. Das liegt aber nicht daran, dass
das '\0' Bytes sind, sondern einfach daran dass memcpy()
Speicherbereiche ohne Ansehen des Inhalts kopiert.
mem...() Funktionen: Arbeiten direkt auf dem Speicher
ohne Ansehen des Inhalts.
memcmp() als Vergleichsfunktion ist
natürlich die Ausnahme.
str...() Funktionen: Arbeiten in einem gewissen Sinne auch
direkt auf dem Speicher. Zusätzlich
wird aber immer berücksichtigt, dass ein
'\0' Byte das Ende des zu bearbeitenden
Bereiches anzeigt.
Daher: Bei mem...() Funktionen muss immer die Länge des zu
bearbeitenden Speicherbereiches angegeben werden. Die mem...()
Funktionen treffen keinerlei Annahmen darüber, was sich im
Speicher an den angegebenen Stellen verbirgt. Für die mem...()
Funktionen ist das einfach nur eine Abfolge an Bytes.
Die str...() Funktionen in der 'klassischen Variante', bekommen
keine Längeninformation mit, sondern leiten diese vom Auftreten
des '\0' Bytes ab. Es gibt also ein spezielles Byte, dass die
Arbeit der str...() Funktion leitet. Von dieser einen Ausnahme
abgesehen kümmern sich auch die str...() Funktionen nicht weiter
um den Byte-Inhalt der bearbeiteten Speicherfelder.
Da sich aber die 'klassischen str...() Funktionen' als relativ
gefährlich herausgestellt haben, hat es im Lauf der Zeit eine
Erweiterung um die 'n' Funktionen gegeben (strncpy, strncmp),
bei denen zusätzlich noch Längeninformation mitgegeben werden
muss. Diese Funktionen benutzten dann zusätzlich zum '\0' Byte
noch diese Längeninformation um sicherzustellen, dass Speicher-
bereiche nicht überlaufen werden. Es gilt: Ein String ist dann
zu Ende, wenn entweder der übergebene Längenparameter aufgebraucht
ist oder ein '\0' Zeichen angetroffen wurde. Je nachdem was zuerst
auftritt. Bei den 'n' Funktionen kann es auch passieren, dass bei
einem Ergebnisstring kein '\0' auftaucht, weil die Längenangabe
eines Zieles nicht gross genug war um diesen String komplett
aufzunehmen.
Die Erfahrung zeigt, dass die Funktionen strncpy() und vor allem
strncat() mehr Gefahren als Nutzen darstellen. Beiden fehlt gern die
Null am Ende, und strncat() stellt keineswegs sicher, dass der
Zielstring nicht überläuft, das "n" bezieht sich ja nicht auf dem Platz
im Zielpuffer, sondern auf die Länge vom Quellstring.
Empfehlung: Wenn die string-Library nicht sowieso schon bessere
Versionen davon zur Verfügung stellt: Finger weg davon und eigene
sichere Versionen basteln.
>> Der einzige Unterschied zu memcpy ist>> also, daß bei letzterem hinter dem Ursprungsstringende der Rest>> mit Nullen aufgefüllt wird (was in 99% der Fälle niemanden>> interessiert).> Äh, nein, das kann man so nicht sagen.
Jetzt mal abgesehen davon, daß ich den Satz noch umformuliert hatte,
wodurch »letzterem« plötzlich keinen Bezug mehr hatte (sorry!), kann man
das m.E. auch nach Deiner Erklärung immer noch so sagen:
* Kommt keine Null innerhalb der angegebenen Länge, verhalten sie
sich gleich
* Kommt eine Null, wird bei strncpy hinter dem Ursprungsstringende
der Rest mit Nullen aufgefüllt (wofür sich wie gesagt normalerweise
niemand für interessiert, wenn das Ergebnis als String genutzt wird)
Und so bleibt meine Frage: warum hat man das so gemacht? Das verstehe
ich wirklich nicht.