http://www.pronix.de -> Forum -> C-Programmieren -> Code-Schnipsel

Unterseiten

Code-Schnipsel

Moderatoren: broesel, Martin Conrad, Patrick

Thema: [EDIT] - Elegantere Alternativen zu strncpy und strncat

  • (nur registrierte Mitglieder)
Wer oft mit strncpy oder strncat arbeitet, kennt das Problem.


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.
 
Hi, die von dir vorgestellten Funktionen sind kein Ersatz für strncpy bzw strncat sondern für strcpy bzw. strcat, da Du eigentlich nicht die Anzahl zu kopierender Zeichen angibst sondern die Größe des Zielbuffers.

Wer Visual C++ verwendet kann strcpy, strncpy, strcat bzw. strncat durch die entsprechenden *_s Funktionen strcpy_s, strncpy_s, strcat_s, strncat_s ersetzten.
 
  • (nur registrierte Mitglieder)