Code-Schnipsel
Moderatoren: broesel, Martin Conrad, PatrickThema: [EDIT] - Elegantere Alternativen zu strncpy und strncat
[EDIT] - Elegantere Alternativen zu strncpy und strncat
norman am 27.03.2009 um 16:44
char src[10], dest[10];
char *strncpy(char *dest, const char *src, size_t n);
Wenn man nicht sorgfaeltig aufpasst, kann es passieren, dass man fuer `n` sizeof(src), anstelle von sizeof(src) - 1 uebergibt. Konsequenz ist, dass dest nicht NULL-terminiert und somit fuer die weitere Stringverarbeitung mit Standard-C nicht tauglich ist.
Aehnlich verfaehrt es mit:
char src[10], dest[20];
char *strncat(char *dest, const char *src, size_t n);
Es kann passieren, dass der resultierende String nicht terminiert ist, und der Programmierer hat in beiden Faellen keine Moeglichkeit dies festzustellen.
Konsistenter und uebersichtlicher sind die Alternativen
size_t strlcpy(char *dst, const char *src, size_t size);
size_t strlcat(char *dst, const char *src, size_t size);
Hier faellt auf, dass die Funktionen keinen Zeiger auf einen String zurueckgeben, sondern eine Groesze. Zurueckgegeben wird naehmlich die Anzahl der Zeichen die insgesamt geschrieben werden muessen, nicht wieviele tatsaechlich geschrieben wurden. Als `size` wird die Groesze des Arrays angegeben, dass Nullbyte muss nicht abgezogen werden. Da der String immer NULL-terminiert wird, kann man einfach feststellen, ob eine Kuerzung vorgenommen wurde oder nicht. Der zurueckgegebene Wert muss daher kleiner als der Wert von size sein.
len = strlcpy(dest, src, sizeof(dest);
if (len >= sizeof(dest))
return ENAMETOOLONG;
Wer sich mit diesen Funktionen beschaeftigen moechte, dem sei folgender Artikel ans Herz gelegt:
http://www.gratisoft.us/todd/papers/strlcpy.html
Zu beachten gilt jedoch:
Diese Funktionen sind nicht Teil des ANSI-Standards und somit nicht portabel. Unter allen *BSD-Derivaten findet sich diese Funktion in der libc, unter Solaris findet sich eine veraenderte Version, unter Linux, welches die glibc nutzt, gar nicht. Daher ist es sinnvoll, diese Funktionen selber immer mitzuliefern, sodass das Portabilitaetsproblem erledigt ist.
Fazit:
Die alternativen Funktionen bieten dem Programmierer die Moeglichkeit, nach der Stringmanipulation auf Kuerzung zu pruefen und den Zielspeicher entsprechend dem Rueckgabewert aufzuruesten, oder eine Fehlermeldung auszugeben. Ausserdem vereinfachen sie den Umgang mit `size`, da hier das Nullbyte nicht mehr beruecksichtigt werden muss.
Was noch erwaehneswert ist: strlcpy() ist deutlich schneller als ihr Pendant strncpy(), weil sie nicht den restlichen String mit Nullbytes fuellt.
Re: Elegantere Alternativen zu strncpy und strncat
scusi71 am 23.07.2009 um 10:53
Wer Visual C++ verwendet kann strcpy, strncpy, strcat bzw. strncat durch die entsprechenden *_s Funktionen strcpy_s, strncpy_s, strcat_s, strncat_s ersetzten.
