| 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;
}