Hi Leuts, kann mir mal jemand erklären, worin der Unterschied zwischen "strncpy (x, y, 5) und memcpy (y,x,5) liegt ? Ein Unterschied ist mir ja klar: strncpy kopiert maximal 5 Bytes, wenn der Sourcestring an Byte [39 mit 0 terminiert, dann hört er da auf. Memcpy kopiert alle 5 Bytes. Aber das meine ich nicht. Ich habe folgendes Problem: uint8_t s1[10], s2[10]; strncpy (s1,"12345"); // geht strncpy (s1, s2, 15); // geht nicht, s2="" memcpy (s2, s1, 15); // geht, s2="12345"; Ein Vertauschen von Source-, und Targetpointer kann auch nicht sein, dann wäre ja s1 mit 0 überschrieben. Warum geht das strncpy nicht (strcpy geht auch nicht)... Greets Karlheinz
Karlheinz Druschel wrote: > kann mir mal jemand erklären, worin der Unterschied zwischen "strncpy > (x, y, 5) und memcpy (y,x,5) liegt ? Dass das eine von y nach x, das andere von x nach y kopiert -- weil du die Argumente vertauscht hast. Die Position ist nämlich bei beiden Funktionen die gleiche. > strncpy (s1,"12345"); // geht Ach? Trotz des fehlenden Parameters? > strncpy (s1, s2, 15); // geht nicht, s2="" Was geht denn nicht? s2 wird dabei jedenfalls nicht geändert... > Ein Vertauschen von Source-, und Targetpointer kann auch nicht sein, > dann wäre ja s1 mit 0 überschrieben. Genau. Weil man die Symptome nicht deuten kann, kann's natürlich daran nicht liegen, dass man die Funktion nicht richtig benutzt... Ja, du hast die beiden Zeiger vertauscht. Ein Blick in ein beliebiges C-Buch hätte dir das sagen können.
Gast
#1104588
Ich denke bei strncpy (s1, s2, 15); ist Source- und Targetpointer vertauscht. bei strncpy (s1,"12345"); ist ja auch der erste Parameter das Ziel, warum soll das später anders sein. Mit strcpy kann man keine 0 kopieren, das geht mit memcpy
Und als Merkhilfe: die Bedeutung der Parameter ist an eine ganz normale Zuweisung angelehnt dst = src; zuerst liest man bei normaler westlicher Leseart von links nach rechts das Ziel (dst == destination) dann die Quelle (src == source). Und genau in dieser Reihenfolge sind auch die Argumente im strcpy / memcpy angeordnet strcpy( dst, src ); Zum Unterschied: Alle Funktionen der str... Familie sind für String Bearbeitung gedacht. Sie wissen also um die Sonderbedeutung eines 0-Bytes bescheid. Wohingegen sich alle Funktionen der mem... Familie auf die reinen Bytes stürzen und alle möglichen Bytewerte gleich behandeln - sprich sie sind ihnen sch.... egal. Der Programmierer will 15 Bytes kopiert haben, also werden auch 15 Bytes kopiert. Generell sollte man, auch wenn man es manchmal sieht, die mem... Funktionen nicht zur Bearbeitung von Strings benutzen. Der str... Funktionsname sagt dir nämlich auch nach 2 Jahren beim erneuten Studium des Codes, das du es hier mit Strings zu tun hast und nicht einfach nur mit irgendwelchen Bytefolgen, die Gott weiss was bedeuten können.
Gast
#1104623
>strcpy( dst, src );
Allerdings haben "normale" Stringfunktionen alle das Problen, dass die
nicht wissen wieviel Platz noch im Puffer ist.
1 | |
2 | |
3 | |
wäre sinnvoller. Aber ich glaube, sowas gibt es mittlerweile als save_str...
Gast
#1104635
> strcpy( dst, src , free ); > free = sizeof(dst)-strlen(dst); Das wird leider recht selten gehen, weil ein sizeof nicht mit einem char* klar kommt, ausdem ist ein zusätzlicher strlen zu langsam. (String muss 2mal geparst werden. es gibt aber wie schon oben gesagt strNcpy da kann man die länge mitgeben.
1 | |
ist so ziemlich das Gleiche wie
1 | |
kbuchegg hats schon richtig gesagt, bei Strings sollte man memcpy nicht benutzen.
Peter wrote: >> strcpy( dst, src , free ); >> free = sizeof(dst)-strlen(dst); > Das wird leider recht selten gehen, weil ein sizeof nicht mit einem > char* klar kommt, ausdem ist ein zusätzlicher strlen zu langsam. (String > muss 2mal geparst werden. > > es gibt aber wie schon oben gesagt strNcpy da kann man die länge > mitgeben. Wobei man auch mal sagen muss, dass nur die alleinige Benutzung von strncpy auch nicht Anlass zu Jubelschreien geben sollte. Denn: Wenn der Platz in dst (ich geh mal davon aus, dass das n die tatsächliche Größe von dst wiederspiegelt und nicht aus irgendwelchen anderen Gründen künstlich kleiner gehalten wird) aufgebraucht ist, dann macht strncpy kein abschliessendes 0-Byte an den Zielstring! Mit
1 | |
2 | |
ist zwar die unmittelbare Gefahr beim strncpy gebannt, allerdings hat man dann in dst keinen gültigen String mehr und wird spätestens bei den nächsten Stringmanipulationen auf die Nase fallen.
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
Beide Varianten sind schon besser. Zumindest wird der String wieder korrekt terminiert. Ob allerdings nachfolgende Programmteile, die sich unter Umständen darauf verlassen, dass der String auch wirklich komplett umkopiert wurde, damit klarkommen dass dem nicht so ist, steht wiederrum auf einem ganz anderen Blatt.
Gast
#1104672
memcpy (dest,src,strlen(src)); so wird das nichts. Wenn schon so ein murks dann so: memcpy (dest,src,strlen(src)+1); sonst ist das char-array in dest eventuell nicht mehr \0 terminiert!!!
Gast
#1104677
Ich sehe mehr das Problem mit dem sizeof(dst) das geht wirklich bloss wenn ein array übergeben wurde. Aber sogut wie jede funktion bekommt ein char* rein. Damit kann sizeof() nicht sinnvollen anfangen.
Gast
#1104698
>Aber sogut wie jede funktion bekommt ein char* rein. Damit kann sizeof() >nicht sinnvollen anfangen. Du hast es erfasst! Deshalb ja der Einwand, das "jede funktion" zusätzlich zum char* noch das die Länge des Puffers braucht, auf das char* zeigt! sizeof() ist ja eine zur Compilezeit bekannte Komstante...
Peter wrote: > Ich sehe mehr das Problem mit dem > > sizeof(dst) Ja, klar. Das war ja auch ein konstruiertes Beispiel. Ist doch im Grunde egal ob da jetzt
1 | |
2 | |
oder
1 | |
2 | |
steht. (Wie also strncpy zu seiner Längenangabe kommt) Der springende Punkt ist: Selbst dann ist das immer noch nur die halbe Miete und man ist global gesehen noch nicht auf der sicheren Seite
Karl heinz Buchegger wrote: > Der springende Punkt ist: Selbst dann ist das immer noch nur die halbe > Miete und man ist global gesehen noch nicht auf der sicheren Seite Worauf ich hinaus will: Es ist nicht so, dass man in einem Programm nur alle strcpy durch strncpy mit korrekter Längenangabe ersetzen muss, und schon ist alles Friede, Freude, Eierkuchen. Nur leider sieht man oft Programme, bei denen sich einem der Eindruck aufdrängt, der Programmierer ist genau dieser Meinung
Antwort schreiben
Bitte melde dich an, um einen Beitrag zu schreiben.