size_t strlen(const char * str)
#include <string.h>
例:・文字列は「\ 0」で終わり、strlen関数は文字列の「\ 0」の前に表示される文字数を返します(「\ 0」は含まれません)。
・パラメータが指す文字列は「\ 0」で終わる必要があります。
・関数の戻り値はsize_tであり、符号なし(エラーが発生しやすい)であることに注意してください。
・strlen関数のアナログ実装
/* strlen example1 */
#include <stdio.h>
#include <string.h>
int main()
{
const char* str1 = "abcdef";
const char* str2 = "bbb";
if (strlen(str2) - strlen(str1) > 0)
{
printf("str2>str1\n");
}
else
{
printf("srt1>str2\n");
}
return 0;
}
/* strlen example2 */
#include <stdio.h>
#include <string.h>
int main ()
{
char str[50];
int len;
strcpy(str, "This is runoob.com");
len = strlen(str);
printf("|%s| 的长度是 |%d|\n", str, len);
return(0);
}
カウンターシミュレーションの実装:
/* simulation of strlen function with counter */
#include <stdio.h>
//计数器实现
size_t Strlen(const char* str)
{
size_t count = 0;
while (*str != '\0')
{
++str;
++count;
}
return count;
}
int main()
{
char str[] = "This is runoob.com";
size_t len;
len = strlen(str);
printf("|%s| 的长度是 |%u|\n", str, len);
return 0;
}
再帰的シミュレーションで実現:
/* simulation of strlen function with recursion */
#include <stdio.h>
//递归实现
size_t Strlen(const char* str)
{
if (*str != '\0')
{
return Strlen(str + 1) + 1;
}
else
return 0;
}
int main()
{
char str[] = "This is runoob.com";
size_t len;
len = Strlen(str);
printf("|%s| 的长度是 |%u|\n", str, len);
return 0;
}
ポインタアドレス差分法を使用して、以下をシミュレートおよび実現します。
/* simulation of strlen function with indicator */
#include <stdio.h>
//指针地址差实现
size_t strlen(const char* str)
{
const char* eos = str;
while (*eos++);
return (eos - str - 1);
}
int main()
{
char str[] = "This is runoob.com";
size_t len;
len = strlen(str);
printf("|%s| 的长度是 |%u|\n", str, len);
return 0;
}
ライブラリでの実装:
/*strlen in lib*/
size_t __cdecl strlen (
const char * str
)
{
const char *eos = str;
while( *eos++ ) ;
return( eos - str - 1 );
}
char * strcpy(char * dest、const char * src)
#include <string.h>
例:dest-コピーされたコンテンツを格納するために使用されるターゲット配列を指します。
src-コピーする文字列。
/* strcpy example1 */
#include <stdio.h>
#include <string.h>
int main()
{
char src[40];
char dest[100];
memset(dest, '\0', sizeof(dest));
strcpy(src, "This is runoob.com");
strcpy(dest, src);
printf("最终的目标字符串: %s\n", dest);
return(0);
}
/* strcpy example2 */
#include <stdio.h>
#include <string.h>
int main ()
{
char str1[]="Sample string";
char str2[40];
char str3[40];
strcpy (str2,str1);
strcpy (str3,"copy successful");
printf ("str1: %s\nstr2: %s\nstr3: %s\n",str1,str2,str3);
return 0;
}
シミュレーションの実装:
/* simulation of strcpy1*/
#include <stdio.h>
#include <string.h>
char* Strcpy(char* dest, const char* src)
{
char * cp = dest;
while (*src)
{
*cp++ = *src++;
}
*cp = *src;
return dest;
}
int main()
{
char src[40];
char dest[100];
memset(dest, '\0', sizeof(dest));
Strcpy(src, "This is runoob.com");
Strcpy(dest, src);
printf("最终的目标字符串: %s\n", dest);
return(0);
}
/* simulation of strcpy2*/
#include <stdio.h>
#include <string.h>
#include <assert.h>
char* Strcpy(char* dest, const char* src)
{
char * cp = dest;
assert(src != NULL);
while (*cp++ = *src++);
return dest;
}
int main()
{
char src[40];
char dest[100];
memset(dest, '\0', sizeof(dest));
Strcpy(src, "This is runoob.com");
Strcpy(dest, src);
printf("最终的目标字符串: %s\n", dest);
return(0);
}
ライブラリでの実装:
/*strcpy in lib*/
char * __cdecl strcpy(char * dst, const char * src)
{
char * cp = dst;
while (*cp++ = *src++)
; /* Copy src over dst */
return(dst);
}
char * strcat(char * dest、const char * src)
#include <string.h>
例:dest-C文字列を含み、追加された文字列を保持するのに十分な大きさのターゲット配列を指します。
src-追加する文字列を指します。ターゲット文字列は上書きされません。
/* strcat example */
#include <stdio.h>
#include <string.h>
int main ()
{
char src[50], dest[50];
strcpy(src, "This is source");
strcpy(dest, "This is destination");
strcat(dest, src);
printf("最终的目标字符串: |%s|", dest);
return(0);
}
シミュレーションの実装:
/* simulation of strcat*/
#include <stdio.h>
#include <string.h>
#include <assert.h>
char* Strcat(char* dest, const char* src)
{
char * cp = dest;
/*while (*cp)
++cp;*/
if (*cp)
while (*(++cp));
assert(src != NULL);
while (*cp++ = *src++);
return dest;
}
int main()
{
char src[50], dest[50];
strcpy(src, "This is source");
strcpy(dest, "This is destination");
Strcat(dest, src);
printf("最终的目标字符串: |%s|", dest);
return(0);
}
ライブラリでの実装:
/*strcat in lib*/
char * __cdecl strcat (
char * dst,
const char * src
)
{
char * cp = dst;
while( *cp )
cp++; /* find end of dst */
while( *cp++ = *src++ ) ; /* Copy src to end of dst */
return( dst ); /* return dst */
}
int strcmp(const char * str1、const char * str2)
#include <string.h>
例:str1-比較される最初の文字列。
str2-比較する2番目の文字列。
戻り値が0未満の場合、str1がstr2よりも小さいことを意味します。
戻り値> 0の場合、str2がstr1より小さいことを意味します。
戻り値= 0の場合、str1がstr2と等しいことを意味します。
/* strcmp example */
#include <stdio.h>
#include <string.h>
int main ()
{
char str1[15];
char str2[15];
int ret;
strcpy(str1, "abcdef");
strcpy(str2, "ABCDEF");
ret = strcmp(str1, str2);
if(ret < 0)
{
printf("str1 小于 str2");
}
else if(ret > 0)
{
printf("str2 小于 str1");
}
else
{
printf("str1 等于 str2");
}
return(0);
}
シミュレーションの実装:
/* simulation of strcmp*/
#include <stdio.h>
#include <string.h>
int Strcmp(const char* src, const char* dst)
{
while ( (*src && *dst) && *src++ == *dst++); //*src != '\0'&& *dst != '\0' --> *src && *dst
if (!*src && !*dst) return 0;
else if (!*src) return -1;
else if (!*dst) return 1;
else
return *src - *dst;
}
int main()
{
char str1[15];
char str2[15];
int ret;
strcpy(str1, "abcdef");
strcpy(str2, "ABCDEF");
ret = Strcmp(str1, str2);
if (ret < 0)
{
printf("str1 小于 str2");
}
else if (ret > 0)
{
printf("str2 小于 str1");
}
else
{
printf("str1 等于 str2");
}
return(0);
}
ライブラリでの実装:
/*strcmp in lib*/
int __cdecl strcmp (
const char * src,
const char * dst
)
{
int ret = 0 ;
while( ! (ret = *(unsigned char *)src - *(unsigned char *)dst) && *dst)
++src, ++dst;
if ( ret < 0 )
ret = -1 ;
else if ( ret > 0 )
ret = 1 ;
return( ret );
}
char * strncpy(char * dest、const char * src、size_t n)
#include <string.h>
例:dest-コピーされたコンテンツを格納するために使用されるターゲット配列を指します。
src-コピーする文字列。
n-ソースからコピーされる文字数。
この関数は、最終的にコピーされた文字列を返します。
/* strncpy example */ //不追加'\0'
#include <stdio.h>
#include <string.h>
int main()
{
char src[40];
char dest[12];
memset(dest, '\0', sizeof(dest));
strcpy(src, "This is runoob.com");
strncpy(dest, src, 10);
printf("最终的目标字符串: %s\n", dest);
return(0);
}
シミュレーションの実装
/* simulation of strncpy*/ //不追加'\0'
#include <stdio.h>
#include <string.h>
char* Strncpy(char* dest, const char* src, size_t n)
{
char* cp = dest;
while (n--)
{
*cp++ = *src++;
}
return dest;
}
int main()
{
char src[40];
char dest[12];
memset(dest, '\0', sizeof(dest));
strcpy(src, "This is runoob.com");
Strncpy(dest, src, 10);
printf("最终的目标字符串: %s\n", dest);
return(0);
}
ライブラリでの実装:
/*Strncpy in lib*/
char * __cdecl strncpy (
char * dest,
const char * source,
size_t count
)
{
char *start = dest;
while (count && (*dest++ = *source++)) /* copy string */
count--;
if (count) /* pad out with zeroes */
while (--count)
*dest++ = '\0';
return(start);
}
char * strncat(char * dest、const char * src、size_t n)
#include <string.h>
例:dest-C文字列を含み、追加のnull文字を含む追加された文字列を保持するのに十分な大きさのターゲット配列を指します。
src-追加する文字列。
n-追加する最大文字数。
戻り値:
この関数は、最終的なターゲット文字列destへのポインタを返します
/* strncat example */ //追加'\0'
#include <stdio.h>
#include <string.h>
int main ()
{
char src[50], dest[50];
strcpy(src, "This is source");
strcpy(dest, "This is destination");
strncat(dest, src, 15);
printf("最终的目标字符串: |%s|", dest);
return(0);
}
シミュレーションの実装:
/* simulation of strncat*/
#include <stdio.h>
#include <string.h>
char* Strncat(char* dest, const char* src, size_t n)
{
char* cp = dest;
if(*cp)
while (*(++cp)); //如果dest第一个是\0元素,防止从从它后面开始复制
while (n--)
{
if(!(*cp++ = *src++)) //防止越界写
return dest;
}
*cp = '\0';
return dest;
}
int main()
{
char src[50], dest[50] = {0};
strcpy(src, "This is source");
//strcpy(dest, "This is destination");
Strncat(dest, src, 15);
printf("最终的目标字符串: |%s|", dest);
return(0);
}
ライブラリでの実装:
/*Strncat in lib*/ //追加'\0'
char * __cdecl strncat (
char * front,
const char * back,
size_t count
)
{
char *start = front;
while (*front++)
;
front--;
while (count--)
if (!(*front++ = *back++))
return(start);
*front = '\0'; //追加'\0'
return(start);
}
int strncmp(const char * str1、const char * str2、size_t n)
#include <string.h>
例:str1-比較される最初の文字列。
str2-比較する2番目の文字列。
n-比較する最大文字数。
戻り値
この関数の戻り値は次のとおりです。
戻り値<0の場合、str1がstr2よりも小さいことを意味します。
戻り値> 0の場合、str2がstr1より小さいことを意味します。
戻り値= 0の場合、str1がstr2と等しいことを意味します。
/* strncmp example */
#include <stdio.h>
#include <string.h>
int main ()
{
char str1[15];
char str2[15];
int ret;
strcpy(str1, "abcdef");
strcpy(str2, "ABCDEF");
ret = strncmp(str1, str2, 4);
if(ret < 0)
{
printf("str1 小于 str2");
}
else if(ret > 0)
{
printf("str2 小于 str1");
}
else
{
printf("str1 等于 str2");
}
return(0);
}
シミュレーションの実装:
/* simulation of strncmp1*/
#include <stdio.h>
#include <string.h>
int Strncmp(const char* str1, const char* str2, size_t n)
{
while (n && (*str1 && *str2) && (*str1++ == *str2++)) n--;
if (!*str1 && !*str2) return 0;
else if (!*str1) return -1;
else if (!*str2) return 1;
else return *str1 - *str2;
}
int main()
{
char str1[15];
char str2[15];
int ret;
strcpy(str1, "abcdef");
strcpy(str2, "ABCDEF");
ret = strncmp(str1, str2, 4);
if (ret < 0)
{
printf("str1 小于 str2");
}
else if (ret > 0)
{
printf("str2 小于 str1");
}
else
{
printf("str1 等于 str2");
}
return(0);
}
/* simulation of strncmp2*/
#include <stdio.h>
#include <string.h>
int Strncmp(const char* str1, const char* str2, size_t n)
{
int res = 0;
while (n && (*str1 && *str2) && !(res = *str1++ - *str2++)) n--;
if (!n) return 0;
if (res < 0) return -1;
else return 1;
}
int main()
{
char str1[15];
char str2[15];
int ret;
strcpy(str1, "ABCdef");
strcpy(str2, "ABCDEF");
ret = strncmp(str1, str2, 3);
if (ret < 0)
{
printf("str1 小于 str2");
}
else if (ret > 0)
{
printf("str2 小于 str1");
}
else
{
printf("str1 等于 str2");
}
return(0);
}
/* simulation of strncmp3 鲍*/
#include <stdio.h>
#include <string.h>
int Strncmp(
const char* first,
const char* last,
size_t count)
{
assert(first != NULL);
assert(last != NULL);
while (count && *first == *last)
{
first++,last++;
count--;
}
return (int)(*first - *last);
}
int main()
{
char str1[15];
char str2[15];
int ret;
strcpy(str1, "ABCdef");
strcpy(str2, "ABCDEF");
ret = strncmp(str1, str2, 3);
if (ret < 0)
{
printf("str1 小于 str2");
}
else if (ret > 0)
{
printf("str2 小于 str1");
}
else
{
printf("str1 等于 str2");
}
return(0);
}
ライブラリでの実装:
/*Strncmp in lib*/
int __cdecl strncmp
(
const char *first,
const char *last,
size_t count
)
{
size_t x = 0;
if (!count)
{
return 0;
}
/*
* This explicit guard needed to deal correctly with boundary
* cases: strings shorter than 4 bytes and strings longer than
* UINT_MAX-4 bytes .
*/
if( count >= 4 )
{
/* unroll by four */
for (; x < count-4; x+=4)
{
first+=4;
last +=4;
if (*(first-4) == 0 || *(first-4) != *(last-4))
{
return(*(unsigned char *)(first-4) - *(unsigned char *)(last-4));
}
if (*(first-3) == 0 || *(first-3) != *(last-3))
{
return(*(unsigned char *)(first-3) - *(unsigned char *)(last-3));
}
if (*(first-2) == 0 || *(first-2) != *(last-2))
{
return(*(unsigned char *)(first-2) - *(unsigned char *)(last-2));
}
if (*(first-1) == 0 || *(first-1) != *(last-1))
{
return(*(unsigned char *)(first-1) - *(unsigned char *)(last-1));
}
}
}
/* residual loop */
for (; x < count; x++)
{
if (*first == 0 || *first != *last)
{
return(*(unsigned char *)first - *(unsigned char *)last);
}
first+=1;
last+=1;
}
return 0;
}
char * strstr(const char * haystack、const char * needle)
#include <string.h>
例:haystack-取得するC文字列。
針-干し草の山の文字列で検索される小さな文字列。
戻り値:
この関数は、干し草の山に針のひもが最初に現れる位置を返します。見つからない場合はnullを返します。
/* strstr example */
#include <stdio.h>
#include <string.h>
int main()
{
const char haystack[20] = "RUNOOB";
const char needle[10] = "NOOB";
const char* ret = NULL;
ret = strstr(haystack, needle);
printf("子字符串是: %s\n", ret);
return(0);
}
関数strstrのプロトタイプはchar * strstr(char * str1、char * str2)です。その関数は、str1で指定された文字列str2が最初に出現する位置を返すことです。
シミュレーションの実装:
/*simulation of strstr1*/
#include <stdio.h>
#include <string.h>
char* Strstr(const char* str1, const char* str2)
{
const char* p1 = str1;
while (*p1++); //p指向'\0'后面
int length1 = p1 - str1 - 1;
const char* p2 = str2;
while (*p2++); //p指向'\0'后面
int length2 = p2 - str2 - 1;
//while(*p2) p2++; //p指向'\0'
//int length2 = p2 - str2;
int nums = length1 - length2 + 1;
for (int i = 0; i < nums; ++i)
{
if (!strncmp(str1 + i, str2, length2))
return (char*)(str1 + i);
}
return nullptr;
}
int main()
{
char haystack[20] = "RUNOOB";
char needle[10] = "NOOB";
char* ret = NULL;
ret = Strstr(haystack, needle);
printf("子字符串是:%s\n", ret);
return(0);
}
/*simulation of strstr2*/
#include <stdio.h>
#include <string.h>
char* Strstr(const char* str1, const char* str2)
{
const char* p1 = str1;
while (*p1++); //p指向'\0'后面
int length1 = p1 - str1 - 1;
const char* p2 = str2;
while (*p2++); //p指向'\0'后面
int length2 = p2 - str2 - 1;
//while(*p2) p2++; //p指向'\0'
//int length2 = p2 - str2;
int nums = length1 - length2 + 1;
for (int i = 0; i < nums; ++i)
{
//if (!strncmp(str1 + i, str2, length2))
int flag = 0;
for (int j = 0; j < length2; ++j)
{
if (*(str1 + i + j) == *(str2 + j))
flag = 1;
else
flag = 0;
}
if(flag)
return (char*)(str1 + i);
}
return nullptr;
}
int main()
{
char haystack[20] = "RUNOOB";
char needle[10] = "NOOB";
char* ret = nullptr;
ret = Strstr(haystack, needle);
printf("子字符串是:%s\n", ret);
return(0);
}
/*strstr in lib*/
char * strtok(char * str、const char *区切り文字);
#include <string.h>
例:Cライブラリ関数char * strtok(char *> str、const char * delim)は、文字列strを文字列のセットとして区切り、delimを区切り文字として区切ります。
/* strtok example1 */
#include <stdio.h>
#include <string.h>
int main ()
{
char str[] ="- This, a sample string.";
char * pch;
printf ("Splitting string \"%s\" into tokens:\n",str);
pch = strtok (str," ,.-");
while (pch != NULL)
{
printf ("%s\n",pch);
pch = strtok (NULL, " ,.-");
}
return 0;
}
/* strtok example2 */
#include <string.h>
#include <stdio.h>
int main () {
char str[80] = "This is - www.runoob.com - website";
const char s[2] = "-";
char *token;
/* 获取第一个子字符串 */
token = strtok(str, s);
/* 继续获取其他的子字符串 */
while( token != NULL ) {
printf( "%s\n", token );
token = strtok(NULL, s);
}
return(0);
}
シミュレーションが実行されます。
/*simulation of strtok*/
ライブラリでの実装:
/*strtok in lib 1*/
/* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */
#include <string.h>
char* strtok(char *s, const char *delim)
{
const char *spanp;
int c, sc;
char *tok;
static char *last;
if (s == NULL && (s = last) == NULL)
return (NULL);
/*
* Skip (span) leading delimiters (s += strspn(s, delim), sort of).
* 跳过字符串首部的分隔符
*/
cont:
c = *s++;
for (spanp = delim; (sc = *spanp++) != 0;) {
if (c == sc)
goto cont;
}
/*
*分割符后面没有字符串了
*/
if (c == 0) { /* no non-delimiter characters */
last = NULL;
return (NULL);
}
tok = s - 1; /*分割符后面还有字符串,将tok指向字符串首部(不包括分隔符)*/
/*
* Scan token (scan for delimiters: s += strcspn(s, delim), sort of).
* Note that delim must have one NUL; we stop if we see that, too.
* 循环字符串中的字符,直到找到分隔符或者结束符,并替换成结束符
*/
for (;;) {
c = *s++;
spanp = delim;
/*
*判断字符串中的某字符是否是分割符中的字符
*如果是,将分隔符替换成结束符并返回tok;
*如果不是,继续判断下一个字符
*/
do {
if ((sc = *spanp++) == c) {
if (c == 0)
s = NULL;
else
s[-1] = 0;
last = s;
return (tok);
}
} while (sc != 0);
}
/* NOTREACHED */
}
/*strtok in lib 2*/
#ifdef _SECURE_VERSION
#define _TOKEN *context
#else /* _SECURE_VERSION */
#define _TOKEN ptd->_token
#endif /* _SECURE_VERSION */
#ifdef _SECURE_VERSION
char * __cdecl strtok_s (
char * string,
const char * control,
char ** context
)
#else /* _SECURE_VERSION */
char * __cdecl strtok (
char * string,
const char * control
)
#endif /* _SECURE_VERSION */
{
unsigned char *str;
const unsigned char *ctrl = control;
unsigned char map[32];
int count;
#ifdef _SECURE_VERSION
/* validation section */
_VALIDATE_RETURN(context != NULL, EINVAL, NULL);
_VALIDATE_RETURN(string != NULL || *context != NULL, EINVAL, NULL);
_VALIDATE_RETURN(control != NULL, EINVAL, NULL);
/* no static storage is needed for the secure version */
#else /* _SECURE_VERSION */
_ptiddata ptd = _getptd();
#endif /* _SECURE_VERSION */
/* Clear control map */
for (count = 0; count < 32; count++)
map[count] = 0;
/* Set bits in delimiter table */
do {
map[*ctrl >> 3] |= (1 << (*ctrl & 7));
} while (*ctrl++);
/* Initialize str */
/* If string is NULL, set str to the saved
* pointer (i.e., continue breaking tokens out of the string
* from the last strtok call) */
if (string)
str = string;
else
str = _TOKEN;
/* Find beginning of token (skip over leading delimiters). Note that
* there is no token iff this loop sets str to point to the terminal
* null (*str == '\0') */
while ( (map[*str >> 3] & (1 << (*str & 7))) && *str )
str++;
string = str;
/* Find the end of the token. If it is not the end of the string,
* put a null there. */
for ( ; *str ; str++ )
if ( map[*str >> 3] & (1 << (*str & 7)) ) {
*str++ = '\0';
break;
}
/* Update nextoken (or the corresponding field in the per-thread data
* structure */
_TOKEN = str;
/* Determine if a token has been found. */
if ( string == str )
return NULL;
else
return string;
}
ストラー
#include <string.h>
例:Cライブラリ関数char * strerror(int errnum)は、内部配列からエラー番号errnumを検索し、エラーメッセージ文字列へのポインタを返します。strerrorによって生成されるエラー文字列は、開発プラットフォームとコンパイラによって異なります。
宣言
以下は、strerror()関数の宣言です。
char * strerror(int errnum)
パラメーター
errnum-エラー番号、通常はerrno。
戻り値
この関数は、エラーerrnumを説明するエラー文字列へのポインタを返します。
/* strerror example */
#include <stdio.h>
#include <string.h>
#include <errno.h>
int main ()
{
FILE *fp;
fp = fopen("file.txt","r");
if( fp == NULL )
{
printf("Error: %s\n", strerror(errno));
}
return(0);
}