Autor: | Wojciech Muła |
---|---|
Dodany: | 21.11.2001 |
Aktualizacja: | 13.10.2005 |
Ot tak, dla rozrywki, postanowiłem samodzielnie zakodować większość funkcji dostępnych w string.h. Może się przydać do szkoły lub na uczelnie. Dokładne opisy funkcji są dostępne pod adresem http://www.delorie.com/djgpp/doc/libc/.
Przedstawię również kilka dodatkowych, niestandardowych funkcji, które mogą się przydać.
Funkcja kopiuje łańcuch znaków.
char *strcpy(char *dest, const char *src) { char* p=dest; while (*dest++ = *src++); return p; }
Funkcja dołącza łańcuch.
char *strcat(char *dest, const char *src) { char* p=dest; while (*dest) dest++; /* przejdź na koniec łańcucha docelowego */ while (*dest++ = *src++); /* dołącz łańcuch źródłowy */ return p; }
Jest to równoważne:
strcpy(dest[strlen(dest)+1], src);
Funkcja zwraca wskaźnik do pierwszego wystąpienia znaku c, jeśli nie zostanie on znaleziony wynikiem funkcji jest NULL.
char *strchr(const char *s, int c) { char* temp = (char*)s; while (*temp && *temp != c) temp++; if (*temp == '\0') return NULL; return temp; }
Funkcja zwraca różnicę kodów ASCII pierwszego różniącego się znaku. Jeśli porównywane łańcuchy są identyczne zwraca 0.
int strcmp(const char *s1, const char*s2) { while ((*s1) && (*s2) && (*s1==*s2)) s1++, s2++; return (int)*s1-(int)*s2; }
Aby wszystko było w porządku należałoby zrzutować s1 i s2 na char*, gdyż obie zmienne są stałymi wskaźnikami. Nie chcę zaciemniać kodu zbędnymi zmiennymi, poza tym kompilator może rzucić co najwyżej ostrzeżeniem.
Funkcja zwraca indeks pierwszego znaku z s1 należącego do zbioru znaków set.
size_t strcspn(const char *s, const char *set) { size_t pos = 0; char *temp; while (*s) /* przetwarzaj wszystkie znaki łańcucha */ { temp = (char*)set; while (*temp) /* porównaj każdy znak ze zbioru z bieżącym znakiem */ if (*s == *temp) return pos; /* zwróć indeks bieżącego znaku gdy należy on do zbioru */ else temp++; s++; pos++; } return pos; }
Funkcja zwraca długość łańcucha, nie uwzględnia kończącego zera.
size_t strlen(const char* string) { size_t len = 0; while (*string++) len++; return len; }
Funkcja dołącza maksymalnie n znaków.
char* strncat(char *s1, const char *s2, size_t n) { size_t num = 0; char* result = s1; while (*s1) s1++; while ((*s1++ = *s2++) && (++num < n)); *s1 = 0; return result; }
Funkcja porównuje maksymalnie n znaków.
int strncmp(const char *s1, const char *s2, size_t n) { size_t num = 0; while ((*s1) && (*s2) && (*s1==*s2) && (++num < n)) s1++, s2++; return (int)*s1-(int)*s2; }
Funkcja kopiuje maksymalnie n znaków.
char* strncpy(char *s1, const char *s2, size_t n) { char* result = s1; size_t num = 0; while ((*s1++ = *s2++) && (++num < n)); *s1 = 0; /* dopisz kończące zero - w standardzie tego nie ma! */ return result; }
Funkcja zwraca adres pierwszego znaku z s1 należącego do zbioru set.
char* strpbrk(const char *s, const char *set) { char *temp; while (*s) { temp = (char*)set; while (*temp) /* process set */ if (*s == *temp) return (char*)s; else temp++; s++; } return NULL; }
Zwraca adres ostatniego wystąpienia znaku c, lub NULL gdy w łańcuchu s1 nie ma tego znaku.
char *strrchr(const char *s, int c) { char* result = NULL; while (*s) { if (*s == c) result = (char*)s; s++; } return result; }
Funkcja zwraca indeks pierwszego znaku z s1 nie należącego do zbioru znaków set.
size_t strspn(const char *s, const char *set) { size_t pos = 0; char *temp; while (*s) { temp = (char*)set; while (*temp) { if (*s == *temp) break; temp++; } if (*temp == '\0') break; s++; pos++; } return pos; }
Funkcja zwraca adres początku łańcucha s2 występującego w s1.
char* my_strstr(char* s, char* s1) { if ((*s1 == '\0') || (*s == '\0')) return NULL; while (*s) { char* temp1 = s; char* temp2 = s1; while (*temp1 == *temp2 && *temp1 && *temp2) temp1++, temp2++; if (*temp2 == '\0') return s; else if (*temp1 == '\0') return NULL; s++; } }
Funkcja zwraca kolejne słowa (ang. tokens), oddzielone znakami z s2.
char *strtok(char *s1, const char *s2) { static char* result; char* temp; if (s1) result=s1; else while (*result++); temp = (char*)s2; while (*temp) { if (*result == *temp) { temp = (char*)s2; result++; continue; } temp++; } s1 = result; while (*s1) { temp = (char*)s2; while ((*s1 != *temp) && (*temp)) temp++; if (*temp == 0) s1++; else break; } *s1 = 0; return result; }
Można zgrabnie zapisać tę funkcję przy użyciu funkcji strcspn i strspn.
Funkcja odwraca kolejność znaków w łańcuchu.
/* 21.11.2001 char e[256] = "Kajak"; strrev(e); e=="kajaK" */ void strrev(char* e) { char* s=e; char t; if (!*e) return; while (*e) e++; e--; while (s <= e) { t = *s; *s = *e; *e = t; s++; e--; } }
Funkcja „ucina” znaki kończące łańcuch.
/* 12.12.2001, 15.11.2002 char s[256] = "jakiś tekst----------------"; strtim(s, '-'); s == "jakiś tekst" */ char* strtrim(const char *s, char c) { char* l = s; s--; while (*(++s)) if (*s != c) l = s; *l = '\0'; return (char*)s; }
Funkcja zamienia znaki.
/* 13.12.2001 char *s = "long file name.mp3"; strreplchar(s, ' ', '_'); s=="long_file_name.mp3" */ char* strreplchar(char *str, char from, char to) { char *c = str; while (*c) { if (*c == from) *c = to; c++; } return str; }
Funkcja kopiuje łańcuchy pomijając wskazany znak.
/* 12.12.2001 char *s = " te sp a cje s ą zupe łnie zbęd n e"; char d[256]; strigniore(d,s, ' '); d=="tespacjesązupełniezbędne" */ char* strignore(char* dst, const char* src, char c) { char *s = (char*)src; char *d = dst; while (*s) { if (*s != c) *d++ = *s; s++; } *d = 0; return dst; }
Funkcja kopiuje łańcuch pomijając powtarzające się znaki.
/* 12.12.2001 char *s = "1111122233344445555555666666677777778888888"; char d[256]; strremdup(d, s); d=="12345678" */ char* strremdup(char* dst, const char* src) { char *s = (char*)src; char *d = dst; char last = 0; while (*s) { if (*s != last) *d++ = last = *s; s++; } *d = 0; return dst; }
Funkcja usuwa nadmiarowe spacje.
/* 13.08.2002 char *s = " Linux does it better "; compresspaces(s); s = " Linux does it better " */ char* compresspaces(const char* S) { char *s = (char*)S; char prev = '1'; while (*S) { if ((prev != ' ') || (*S != ' ')) *s++ = *S; prev = *S++; } *s = '\0'; return S; }
Funkcja usuwa wskazany fragment łańcucha.
/* 7.12.2001 char *s = "to słowo jest zbędne"; strremove(s, 3, 6); s=="to jest zbędne" */ char* strremove(char* str, int pos, int length) { char* p = str+pos; char* t = str+pos+length; if (p < str+strlen(str)) if (t > str+strlen(str)) str[pos]=0; else { while (*t) *p++ = *t++; *p=0; } return str; }
/* 13.12.2001 char s[256] = "http://.republika.pl"; strinsert(s, "asmcorner", 6); s=="http://asmcorner.republika.pl" */ char* strinsert(char* str, const char* new_str, int pos) { int str_len = strlen(str); int new_len = strlen(new_str); int tocopy = str_len - pos; /* 14 znaków do skopiowania */ char* s = str + str_len-1; char* e = s + new_len; while (tocopy--) *e-- = *s--; /* str == "http://.republik.republika.pl" */ s = str+pos; /* po czym skopiuje */ e = (char*)new_str; /* łańcuch na właściwą pozycję */ while (*e) *s++ = *e++; /* str == "http://asmcorner.republika.pl" */ return str; }
Funkcja oblicza ilość wystąpień znaku.
/* 7.12.2001 char *s = "xx001x011" if (strchrc(s, 'x') == 3) puts("3 razy X") */ size_t strchrc(const char* str, char c) { size_t num = 0; char *n = (char*)str; while (*n) { if ( (n=(char*)strchr(n, c))==NULL) break; num++; n+=1; } return num; }
/* 7.12.2001 char *s = "być może (albo na pewno) tak nie jest"; char d[256]; match_parentcheses(d, s, '(', ')'); d == "(albo na pewno)" */ char* match_parentcheses(char* dst, const char* src, char left, char right) { char *A = (char*)strchr(src, left); char *B = (char*)strchr(src, right); if ((A) && (B) && (A < B)) { strncpy(dst, A, B-A+1); dst[B-A+1] = 0; } else dst[0] = 0; return dst; }
/* 7.12.2001 char *s = "być może (albo na pewno) tak nie jest"; char d[256]; match_parentcheses(d, s, '(', ')'); d == "albo na pewno" */ char* match_parentcheses2(char* dst, const char* src, char left, char right) { char *A = (char*)strchr(src, left); char *B = (char*)strchr(src, right); if ((A) && (B) && (A < B)) { strncpy(dst, A+1, B-A-1); dst[B-A-1] = 0; } else dst[0] = 0; return dst; }
/* 7.12.2001 char *s = "niemniej jednak *istotą* sprawy..." char d[256]; match_pair(d, s, '*'); d=="*istotą*" */ char* match_pair(char* dst, const char* src, char c) { char *A = (char*)strchr(src, c); char *B = (char*)strchr(A+1, c); if ((A) && (B)) { strncpy(dst, A, B-A+1); dst[B-A+1] = 0; } else dst[0] = 0; return dst; }
/* 7.12.2001 char *s = "niemniej jednak *istotą* sprawy..." char d[256]; match_pair(d, s, '*'); d=="istotą" */ char* match_pair2(char* dst, const char* src, char c) { char *A = (char*)strchr(src, c); char *B = (char*)strchr(A+1, c); if ((A) && (B)) { strncpy(dst, A+1, B-A-1); dst[B-A-1] = 0; } else dst[0] = 0; return dst; }