复制Copying
复制内存memcpy
复制内存块Copy block of memory
void * memcpy ( void * destination, const void * source, size_t num );
结果是数据的二进制副本。
该函数不检查源中的任何终止空字符 - 它总是准确地复制字节数。为避免溢出,目标和源参数指向的数组大小应至少为字节数,并且不应重叠(对于重叠的内存块,memmove 是一种更安全的方法)。
参数Parameters
- destination
- 指向目标数组的指针,类型转换为
void*
类型的指针。
- source
- 指向要复制的数据源的指针,类型转换为
const void*
类型的指针。
- num
- 要复制的字节数。
size_t
是无符号整型。
返回值Return Value
返回目标指针。
例子Example
#include <stdio.h> #include <string.h> struct { char name[40]; int age; } person, person_copy; int main () { char myname[] = "Pierre de Fermat"; //使用memcpy复制字符串 memcpy ( person.name, myname, strlen(myname)+1 ); person.age = 46; //使用memcpy复制结构体 memcpy ( &person_copy, &person, sizeof(person) ); printf ("person_copy: %s, %d \n", person_copy.name, person_copy.age ); return 0; }
输出结果
person_copy: Pierre de Fermat, 46
移动内存memmove
移动内存并不会将源内存的数据清除
void * memmove ( void * destination, const void * source, size_t num );
将字节数的值从源指向的位置转到目标指向的内存块。复制就像使用了中间缓冲区一样,允许目标和源重叠。
源指针和目标指针指向的对象的基础类型与此函数无关;结果是数据的二进制副本。
该函数不检查源中的任何终止空字符 - 它总是准确地复制字节数。
为避免溢出,目标参数和源参数指向的数组的大小应至少为字节数num。
参数和返回值与memcopy相同,功能不同
#include <stdio.h> #include <string.h> int main() { //将very useful复制到了useful后面 char str[] = "memmove can be very useful......"; memmove(str + 20, str + 15, 11); puts(str); return 0; }
输出结果
memmove can be very very useful.
复制字符串strcpy
char * strcpy ( char * destination, const char * source );
将源指向的 C 字符串复制到目标指向的数组中,包括终止的 null 字符(并在该点停止)。
为避免溢出,目标指向的数组的大小应足够长,以包含与源相同的 C 字符串(包括终止空字符),并且不应在内存中与源重叠。
参数Parameters
- destination
- 指向要在其中复制内容的目标数组的指针。
- source
- 要复制的 C 字符串。
返回值Return Value
返回目标指针。
例子Example
#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; }
输出结果
str1: Sample string
str2: Sample string
str3: copy successful
从字符串中复制字符strncpy
char * strncpy ( char * destination, const char * source, size_t num );
从字符串中复制字符Copy characters from string
将源的第一个字符数复制到目标。如果在复制 num 个字符之前找到源 C 字符串的末尾(由 null 字符表示),则目标将填充零,直到总共写入 num 个字符为止。
参数Parameters
- destination
- 指向要在其中复制内容的目标数组的指针。
- source
- 要复制的 C 字符串。
- num
- 要从源复制的最大字符数。
返回值Return Value
返回目标指针。
例子Example
#define _CRT_SECURE_NO_WARNINGS #include <stdio.h> #include <string.h> int main() { char str1[] = "To be or not to be"; char str2[40]; char str3[40]; //复制到大小缓冲区(溢出安全) strncpy(str2, str1, sizeof(str2)); //部分复制(仅 5 个字符) strncpy(str3, str2, 5); str3[5] = '\0'; //手动添加空字符 puts(str1); puts(str2); puts(str3); return 0; }
输出结果
To be or not to be
To be or not to be
To be
串联拼接Concatenation
连接字符串strcat
char * strcat ( char * destination, const char * source );
将源字符串的副本追加到目标字符串。目标中的终止空字符被源的第一个字符覆盖,并且在目标中由两者串联形成的新字符串的末尾包含一个空字符。
目的地和来源不得重叠。
参数Parameters
- destination
- 指向目标数组的指针,该数组应包含 C 字符串,并且足够大以包含串联的结果字符串。
- source
- 要追加的 C 字符串。这不应与目标重叠。
返回值Return Value
返回目标指针。
例子Example
#define _CRT_SECURE_NO_WARNINGS #include <stdio.h> #include <string.h> int main() { char str[80]; strcpy(str, "these "); strcat(str, "strings "); strcat(str, "are "); strcat(str, "concatenated."); puts(str); return 0; }
输出结果
these strings are concatenated.
字符级拼接strncat
char * strncat ( char * destination, const char * source, size_t num );
从字符串追加字符Append characters from string
将源的前 num 个字符追加到目标,外加一个终止空字符。
如果源中 C 字符串的长度小于 num,则仅复制终止空字符之前的内容。
参数Parameters
- destination
- 指向目标数组的指针,该数组应包含一个 C 字符串,并且足够大以包含串联的结果字符串,包括其他 null 字符。
- source
- 要追加的 C 字符串。
- num
- 要追加的最大字符数。
返回值Return Value
返回目标指针。
例子Example
#define _CRT_SECURE_NO_WARNINGS #include <stdio.h> #include <string.h> int main() { char str1[20]; char str2[20]; strcpy(str1, "To be "); strcpy(str2, "or not to be"); strncat(str1, str2, 6); puts(str1); return 0; }
输出结果
To be or not
比较Comparison
比较内存块memcmp
比较两个内存块Compare two blocks of memory
int memcmp ( const void * ptr1, const void * ptr2, size_t num );
将 ptr1 指向的内存块的前 num 字节数与 ptr2 指向的第一个字节数进行比较,如果它们都匹配,则返回零,如果不匹配,则返回一个不同于零的值,表示哪个更大。
请注意,与 strcmp 不同,该函数在找到空字符后不会停止比较。
参数Parameters
- ptr1
- 指向内存块的指针。
- ptr2
- 指向内存块的指针。
- num
- 要比较的字节数。
返回值Return Value
返回一个整数值,该值指示内存块内容之间的关系:
返回值return value | 表明indicates |
<0 | 两个内存块中不匹配的第一个字节在 ptr1 中的值低于 ptr2 中的值(如果评估为无符号字符值) |
=0 | 两个内存块的内容相等 |
>0 | 两个内存块中不匹配的第一个字节在 ptr1 中的值大于在 ptr2 中的值(如果评估为无符号字符值) |
例子Example
#define _CRT_SECURE_NO_WARNINGS #include <stdio.h> #include <string.h> int main() { char buffer1[] = "DWgaOtP12df0"; char buffer2[] = "DWGAOTP12DF0"; int n; n = memcmp(buffer1, buffer2, sizeof(buffer1)); if (n > 0) printf("'%s' is greater than '%s'.\n", buffer1, buffer2); else if (n < 0) printf("'%s' is less than '%s'.\n", buffer1, buffer2); else printf("'%s' is the same as '%s'.\n", buffer1, buffer2); return 0; }
输出结果
‘DWgaOtP12df0’ is greater than ‘DWGAOTP12DF0’.
DWgAOtp12Df0 大于 DWGAOTP12DF0,因为这两个单词中的第一个不匹配字符分别是“g”和“G”,而“g”(103) 的计算结果大于“G”(71)。
比较字符串strcmp
int strcmp ( const char * str1, const char * str2 );
比较两个字符串Compare two strings
此函数开始比较每个字符串的第一个字符。如果它们彼此相等,则继续以下对,直到字符不同或达到终止空字符。
此函数执行字符的二进制比较。
参数Parameters
- ptr1
- 要比较的 C 字符串。
- ptr2
- 要比较的 C 字符串。
返回值Return Value
返回一个整数值,该值指示内存块内容之间的关系:
返回值return value | 表明indicates |
<0 | 第一个不匹配的字符在 ptr1 中的值低于 ptr2 中的值 |
=0 | 两个字符串的内容相等 |
>0 | 第一个不匹配的字符在 ptr1 中的值大于在 ptr2 中的值 |
例子Example
#define _CRT_SECURE_NO_WARNINGS #include <stdio.h> #include <string.h> int main() { char key[] = "apple"; char buffer[80]; do { printf("Guess my favorite fruit? "); fflush(stdout); scanf("%79s", buffer); } while (strcmp(key, buffer) != 0); puts("Correct answer!"); return 0; }
输出结果
Guess my favourite fruit? orange
Guess my favourite fruit? apple
Correct answer!
另一种字符串比较strcoll
int strcoll ( const char * str1, const char * str2 );
将 C 字符串 str1 与 C 字符串 str2 进行比较,两者都根据当前所选 C 区域设置的LC_COLLATE类别进行适当解释。
此函数开始比较每个字符串的第一个字符。如果它们彼此相等,则继续执行下一对,直到字符不同或到达表示字符串末尾的空字符。
此函数的行为取决于所选 C 语言环境LC_COLLATE类别。
使用区域设置比较两个字符串Compare two strings using locale
参数Parameters
- ptr1
- 要比较的 C 字符串。
- ptr2
- 要比较的 C 字符串。
返回值Return Value
返回一个整数值,该值指示字符串之间的关系:
零值表示两个字符串相等。
大于零的值表示不匹配的第一个字符在 str1 中的值大于在 str2 中的值;小于零的值表示相反的情况。
字符级比较strncmp
int strncmp ( const char * str1, const char * str2, size_t num );
比较两个字符串的字符Compare characters of two strings
将 C 字符串 str1 的字符数与 C 字符串 str2 的字符数进行比较。
此函数开始比较每个字符串的第一个字符。如果它们彼此相等,则继续使用以下对,直到字符不同,直到达到终止的空字符,或者直到两个字符串中的 num 字符匹配,以先发生者为准。
参数Parameters
- ptr1
- 要比较的 C 字符串。
- ptr2
- 要比较的 C 字符串。
- num
- 要比较的最大字符数。
返回值Return Value
返回一个整数值,该值指示内存块内容之间的关系:
返回值return value | 表明indicates |
<0 | 不匹配的第一个字符在 str1 中的值低于 str2 中的值 |
=0 | 两个字符串的内容相等 |
>0 | 第一个不匹配的字符在 str1 中的值大于在 str2 中的值 |
例子Example
#define _CRT_SECURE_NO_WARNINGS #include <stdio.h> #include <string.h> int main() { char str[][5] = { "R2D2" , "C3PO" , "R2A6" }; int n; puts("Looking for R2 astromech droids..."); for (n = 0; n < 3; n++) if (strncmp(str[n], "R2xx", 2) == 0) { printf("found %s\n", str[n]); } return 0; }
输出结果
Looking for R2 astromech droids…
found R2D2
found R2A6
转换字符串strxfrm
size_t strxfrm ( char * destination, const char * source, size_t num );
使用区域设置转换字符串Transform string using locale
根据当前区域设置转换源指向的 C 字符串,并将转换后的字符串的前 num 字符复制到目标,并返回其长度。
或者,该函数可用于仅检索长度,方法是为目标指定空指针,为 num 指定零指针。
目的地和来源不得重叠。
此函数的行为取决于所选 C 语言环境LC_COLLATE类别。
参数Parameters
- destination
- 指向要在其中复制内容的目标数组的指针。
- 如果 num 的参数为零,则它可以是空指针。
- source
- 要转换的 C 字符串。
- num
- 要复制到目标的最大字符数。
返回值Return Value
转换后的字符串的长度,不包括终止 null 字符。
搜索Searching
在内存块中查找字符memchr
const void * memchr ( const void * ptr, int value, size_t num );
void * memchr ( void * ptr, int value, size_t num );
在 ptr 指向的内存块的前几个字节数内搜索第一个出现的值(解释为无符号字符),并返回指向它的指针。
在 ptr 数组上检查的值和每个字节都被解释为无符号字符进行比较。
参数Parameters
- ptr
- 指向执行搜索的内存块的指针。
- value
- 要定位的值。该值作为 int 传递,但该函数使用此值的无符号字符转换执行每字节字节搜索。
- num
- 要分析的字节数。
返回值Return Value
指向 ptr 所指向的内存块中第一个出现的值的指针。
如果未找到该值,该函数将返回空指针。
可移植性Portability
在 C 中,此函数仅声明为:
void * memchr ( const void *, int, size_t );
例子Example
#include <stdio.h> #include <string.h> int main() { char* pch; char str[] = "Example string"; pch = (char*)memchr(str, 'p', strlen(str)); if (pch != NULL) printf("'p' found at position %d.\n", pch - str + 1); else printf("'p' not found.\n"); return 0; }
输出结果
‘p’ found at position 5.
在字符串中查找字符strchr
const char * strchr ( const char * str, int character );
char * strchr ( char * str, int character );
查找字符串中第一个出现的字符Locate first occurrence of character in string
返回指向 C 字符串 str 中第一个出现 character 的指针。
终止空字符被视为 C 字符串的一部分。因此,也可以定位它以检索指向字符串末尾的指针。
参数Parameters
- str
- C 字符串。
- character
- 要定位的字符。它作为其 int 提升传递,但在内部转换回 char 进行比较。
返回值Return Value
指向 str 中第一次出现的 character 的指针。
如果未找到 character,则该函数返回空指针。
可移植性Portability
在 C 中,此函数仅声明为:
char * strchr ( const char *, int );
而不是 C++ 中提供的两个重载版本。
例子Example
#include <stdio.h> #include <string.h> int main() { char str[] = "This is a sample string"; char* pch; printf("Looking for the 's' character in \"%s\"...\n", str); pch = strchr(str, 's'); while (pch != NULL) { printf("found at %d\n", pch - str + 1); pch = strchr(pch + 1, 's'); } return 0; }
输出结果
Looking for the ‘s’ character in “This is a sample string”…
found at 4
found at 7
found at 11
found at 18
strcspn
size_t strcspn ( const char * str1, const char * str2 );
获取范围直到字符串中的字符Get span until character in string
扫描 str1 以查找属于 str2 的任何字符的第一次出现,返回在第一次出现之前读取的 str1 字符数。
搜索包括终止空字符。因此,如果在 str1 中找不到 str2 的任何字符,该函数将返回 str1 的长度。
参数Parameters
- str1
- 要扫描的 C 字符串。
- str2
- 包含要匹配的字符的 C 字符串。
返回值Return Value
str1 的初始部分的长度,不包含属于 str2 的任何字符。
如果在 str1 中找不到 str2 中的任何字符,则这是 str1 的长度。
例子Example
#include <stdio.h> #include <string.h> int main() { char str[] = "fcba73"; char keys[] = "1234567890"; int i; i = strcspn(str, keys); printf("The first number in str is at position %d.\n", i + 1); return 0; }
输出结果
The first number in str is at position 5
strpbrk
const char * strpbrk ( const char * str1, const char * str2 );
char * strpbrk ( char * str1, const char * str2 );
查找字符串中的字符Locate characters in string
返回指向 str1 中属于 str2 的任何字符的第一个匹配项的指针,如果没有匹配项,则返回一个 null 指针。
搜索不包括任一字符串的终止空字符,但到此结束。The search does not include the terminating null-characters of either strings, but ends there.
参数Parameters
- str1
- 要扫描的 C 字符串。
- str2
- 包含要匹配的字符的 C 字符串。
返回值Return Value
指向属于 str2 的任何字符在 str1 中首次出现的指针,如果在终止空字符之前在 str1 中找不到 str2 的任何字符,则为空指针。
如果 str1 中不存在 str2 的任何字符,则返回空指针。
可移植性Portability
在 C 中,此函数仅声明为:
char * strpbrk ( const char *, const char * );
而不是 C++ 中提供的两个重载版本。
例子Example
#include <stdio.h> #include <string.h> int main() { char str[] = "This is a sample string"; char key[] = "aeiou"; char* pch; printf("Vowels in '%s': ", str); pch = strpbrk(str, key); while (pch != NULL) { printf("%c ", *pch); pch = strpbrk(pch + 1, key); } printf("\n"); return 0; }
输出结果
Vowels in ‘This is a sample string’: i i a a e i
strrchr
const char * strrchr ( const char * str, int character );
char * strrchr ( char * str, int character );
查找字符串中最后一个出现的字符Locate last occurrence of character in string
返回指向 C 字符串 str 中最后一个出现的字符的指针。
终止空字符被视为 C 字符串的一部分。因此,也可以定位它以检索指向字符串末尾的指针。
参数Parameters
- str
- C 字符串。
- character
- 要定位的字符。它作为其 int 提升传递,但在内部转换回 char。
返回值Return Value
指向 str 中最后一个出现的字符的指针。
如果未找到该字符,则该函数将返回一个空指针。
可移植性Portability
在 C 中,此函数仅声明为:
char * strrchr ( const char *, int );
而不是 C++ 中提供的两个重载版本。
例子Example
#include <stdio.h> #include <string.h> int main() { char str[] = "This is a sample string"; char* pch; pch = strrchr(str, 's'); printf("Last occurence of 's' found at %d \n", pch - str + 1); return 0; }
输出结果
Last occurrence of ‘s’ found at 18
strspn
size_t strspn ( const char * str1, const char * str2 );
获取字符串中字符集的范围Get span of character set in string
返回 str1 初始部分的长度,该部分仅由属于 str2 的字符组成。
搜索不包括任一字符串的终止空字符,但到此结束。
参数Parameters
- str1
- 要扫描的 C 字符串。
- str2
- 包含要匹配的字符的 C 字符串。
返回值Return Value
str1 的初始部分的长度,仅包含 str2 中出现的字符。The length of the initial portion of str1 containing only characters that appear in str2.
因此,如果 str1 中的所有字符都在 str2 中,则该函数返回整个 str1 字符串的长度,如果 str1 中的第一个字符不在 str2 中,则该函数返回零。Therefore, if all of the characters in str1 are in str2, the function returns the length of the entire str1 string, and if the first character in str1 is not in str2, the function returns zero.
例子Example
#include <stdio.h> #include <string.h> int main() { int i; char strtext[] = "129th"; char cset[] = "1234567890"; i = strspn(strtext, cset); printf("The initial number has %d digits.\n", i); return 0; }
输出结果
The initial number has 3 digits.
strstr
const char * strstr ( const char * str1, const char * str2 );
char * strstr ( char * str1, const char * str2 );
查找子字符串Locate substring
返回指向 str1 中第一次出现的 str2 的指针,如果 str2 不是 str1 的一部分,则返回一个空指针。
匹配过程不包括终止空字符,但它到此为止。
参数Parameters
- str1
- 要扫描的 C 字符串。C string to be scanned.
- str2
- 包含要匹配的字符序列的 C 字符串。C string containing the sequence of characters to match.
返回值Return Value
指向 str2 中指定的整个字符序列在 str1 中首次出现的指针,如果序列在 str1 中不存在,则为 null 指针。A pointer to the first occurrence in str1 of the entire sequence of characters specified in str2, or a null pointer if the sequence is not present in str1.
例子Example
#define _CRT_SECURE_NO_WARNINGS #include <stdio.h> #include <string.h> int main() { char str[] = "This is a simple string"; char* pch; pch = strstr(str, "simple"); if (pch != NULL) strncpy(pch, "sample", 6); puts(str); return 0; }
此示例在 str 中搜索“simple”子字符串,并将该单词替换为“sample”。
输出结果
This is a sample string
strtok
这个解释很麻烦,看下面的示例就很容易理解了
char * strtok ( char * str, const char * delimiters );
将字符串拆分为标记Split string into tokens
对此函数的一系列调用将 str 拆分为标记,这些标记是由 delimiters 中的任何字符分隔的连续字符序列。A sequence of calls to this function split str into tokens, which are sequences of contiguous characters separated by any of the characters that are part of delimiters.
在第一次调用时,该函数需要一个 C 字符串作为 str 的参数,其第一个字符用作扫描令牌的起始位置。在后续调用中,该函数需要一个空指针,并使用最后一个令牌末尾之后的位置作为扫描的新起始位置。On a first call, the function expects a C string as argument for str, whose first character is used as the starting location to scan for tokens. In subsequent calls, the function expects a null pointer and uses the position right after the end of the last token as the new starting location for scanning.
为了确定标记的开头和结尾,该函数首先从起始位置扫描分隔符中未包含的第一个字符(该字符将成为标记的开头)。然后从令牌的开头开始扫描分隔符中包含的第一个字符,该字符将成为令牌的末尾。如果找到终止空字符,扫描也会停止。To determine the beginning and the end of a token, the function first scans from the starting location for the first character not contained in delimiters (which becomes the beginning of the token). And then scans starting from this beginning of the token for the first character contained in delimiters, which becomes the end of the token. The scan also stops if the terminating null character is found.
令牌的此结尾将自动替换为空字符,并且令牌的开头由函数返回。This end of the token is automatically replaced by a null-character, and the beginning of the token is returned by the function.
一旦在对 strtok 的调用中找到 str 的终止空字符,则对此函数的所有后续调用(以空指针作为第一个参数)都将返回空指针。Once the terminating null character of str is found in a call to strtok, all subsequent calls to this function (with a null pointer as the first argument) return a null pointer.
找到最后一个令牌的点由要在下一次调用中使用的函数在内部保留(不需要特定的库实现来避免数据争用)。The point where the last token was found is kept internally by the function to be used on the next call (particular library implementations are not required to avoid data races).
参数Parameters
- str
- 要截断的 C 字符串。请注意,此字符串是通过分解为较小的字符串(标记)来修改的。或者,可以指定空指针,在这种情况下,函数将继续扫描以前成功调用函数的位置。
- delimiters
- 包含分隔符字符的 C 字符串。这些可能因调用而异。
返回值Return Value
如果找到令牌,则指向令牌开头的指针。
否则为空指针。
当在正在扫描的字符串中到达字符串的末尾(即空字符)时,始终返回空指针。
例子Example
#define _CRT_SECURE_NO_WARNINGS #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; }
输出结果
Splitting string “- This, a sample string.” into tokens:
This
a
sample
string
其他Other
memset
void * memset ( void * ptr, int value, size_t num );
填充内存块Fill block of memory
参数Parameters
- ptr
- 指向要填充的内存块的指针。
- value
- 要设置的值。该值作为 int 传递,但该函数使用此值的无符号 char 转换填充内存块。
- num
- 要设置为该值的字节数。
返回值Return Value
返回目标指针。
例子Example
#include <stdio.h> #include <string.h> int main() { char str[] = "almost every programmer should know memset!"; memset(str, '-', 6); puts(str); return 0; }
输出结果
------ every programmer should know memset!
strerror
定义不容易理解,多看看例子
char * strerror ( int errnum );
获取指向错误消息字符串的指针Get pointer to error message string
解释 errnum 的值,生成一个字符串,其中包含描述错误条件的消息,就像由库的函数设置为 errno 一样。Interprets the value of errnum, generating a string with a message that describes the error condition as if set to errno by a function of the library.
返回的指针指向静态分配的字符串,程序不应修改该字符串。对此函数的进一步调用可能会覆盖其内容(不需要特定的库实现来避免数据争用)。The returned pointer points to a statically allocated string, which shall not be modified by the program. Further calls to this function may overwrite its content (particular library implementations are not required to avoid data races).
strerror 生成的错误字符串可能特定于每个系统和库实现。The error strings produced by strerror may be specific to each system and library implementation.
参数Parameters
- errnum
- 错误号。Error number.
返回值Return Value
指向描述错误 errnum 的错误字符串的指针。A pointer to the error string describing error errnum.
例子Example
#define _CRT_SECURE_NO_WARNINGS #include <stdio.h> #include <string.h> #include <errno.h> int main() { FILE* pFile; pFile = fopen("unexist.ent", "r"); if (pFile == NULL) printf("Error opening file unexist.ent: %s\n", strerror(errno)); return 0; }
可能的输出:
Error opening file unexist.ent: No such file or directory