首页 > 代码库 > [C] 语言字符串、文件及内存分配函数

[C] 语言字符串、文件及内存分配函数

一、字符串函数

1、gets()

头文件:#include <stdio.h>

函数原型:char *gets(char *string);

函数说明:从标准输入流(stdin)中读取整行,直至遇到换行符结束,然后丢弃换行符,储存其余字符,并在末尾加上空字符,表示一个字符串;

函数返回值:若成功则返回指向string的指针,否则返回NULL;

备注:与puts()函数配套使用;只知道string的开始出,不知道数组中有多少个元素,超出边界,容易造成缓冲区溢出

2、fgets()

头文件:include<stdio.h>

函数原型:char *fgets(char *string, int size, FILE *stream);

函数说明:从输入流( FILE *stream)中读取整行;如果size设为n,将从输入流中读取n-1个字符,或者遇到换行符结束(包含换行符),存储在string中,并在末尾添加空字符,表示一个字符串;

函数返回值:读取成功,返回读取到的字符串,即string;失败或读到文件结尾返回NULL。因此,我们不能直接通过fgets()的返回值来判断函数是否是出错而终止的,应该借助feof()函数或者ferror()函数来判断;

备注:与fputs()配套使用。

3、puts()

头文件:#include<stdio.h>

函数原型:int puts(char *string);

函数说明:puts()函数用于将一字符串输出到标准输出流(stdout)中,直到遇见结束标志 ‘\0‘,‘\0‘不会被输出到stdout,并在最后增加换行符 ‘\n‘;

返回值:输出成功返回非0值,否则返回0;

4、fputs()

头文件:#include <stdio.h>

函数原型:int fputs(char *string, FILE *stream);

函数说明:fputs()从string的开头向文件写入字符串,直到遇见结束字符 ‘\0‘,‘\0‘ 不会被写入到文件中,不添加换行符;

备注:fputs()可以指定输出的文件流,不会输出多余的字符;puts()只能向 stdout 输出字符串,而且会在最后自动增加换行符。

5、strcat()

头文件:#include <string.h>

函数原型:char *strcat(char *dest, const char *src);

函数说明:strcat() 会将参数 src 字符串复制到参数 dest 所指的字符串尾部;dest 最后的结束字符 NULL 会被覆盖掉,并在连接后的字符串的尾部再增加一个 NULL,空字符是结束标志;

返回值:返回dest 字符串起始地址;

备注:dest 与 src 所指的内存空间不能重叠,且 dest 要有足够的空间来容纳要复制的字符串。

6、strncat()

头文件:#inclue <string.h>

函数原型:char * strncat(char *dest, const char *src, size_t n);

函数说明:strncat()将会从字符串src的开头拷贝n 个字符到dest字符串尾部,dest要有足够的空间来容纳要拷贝的字符串。如果n大于字符串src的长度,那么仅将src全部追加到dest的尾部;strncat()会将dest字符串最后的‘\0‘覆盖掉,字符追加完成后,再追加‘\0‘;

返回值:返回字符串dest。

7、strcmp()

头文件:#include <string.h>

函数原型:int strcmp(const char *s1, const char *s2);

函数说明:strcmp() 用来比较字符串(区分大小写);字符串大小的比较是以ASCII 码表上的顺序来决定,此顺序亦为字符的值。strcmp()首先将s1 第一个字符值减去s2 第一个字符值,若差值为0 则再继续比较下个字符,若差值不为0 则将差值返回。例如字符串"Ac"和"ba"比较则会返回字符"A"(65)和‘b‘(98)的差值(-33);

返回值:若参数s1 和s2 字符串相同则返回0。s1 若大于s2 则返回大于0 的值。s1 若小于s2 则返回小于0 的值;

备注:strcmp() 以二进制的方式进行比较,不会考虑多字节或宽字节字符;如果考虑到本地化的需求,请使用 strcoll()函数。

8、strncmp()

头文件:#include <string.h>

函数原型:int strncmp ( const char * str1, const char * str2, size_t n );

函数说明:strncmp() 用来比较两个字符串的前n个字符,区分大小写;字符串大小的比较是以ASCII 码表上的顺序来决定,此顺序亦为字符的值。strncmp()首先将s1 第一个字符值减去s2 第一个字符值,若差值为0 则再继续比较下个字符,直到字符结束标志‘\0‘,若差值不为0,则将差值返回。例如字符串"Ac"和"ba"比较则会返回字符"A"(65)和‘b‘(98)的差值(-33)。

返回值:若str1与str2的前n个字符相同,则返回0;若s1大于s2,则返回大于0的值;若s1 若小于s2,则返回小于0的值;

备注:要比较的字符包括字符串结束标志‘\0‘,而且一旦遇到‘\0‘就结束比较,无论n是多少,不再继续比较后边的字符。

注意:如果两个字符不同,GCC返回该字符对应的ASCII码的差值,VC返回-1或1。但是让人为难的是,strnicmp()、strcmp()、stricmp()在GCC和VC下都返回-1或1,而不是ASCII的差值。

9、strcpy()

头文件:#include <string.h>

函数原型: char *strcpy(char *dest, const char *src);

函数说明:strcpy() 函数用来复制字符串;strcpy() 把src所指的由‘\0‘结束的字符串(包含空字符)复制到dest 所指的数组中(且可以不必指向数组的开始),返回指向 dest 字符串的起始地址,即只拷贝空字符(包含空字符)之前的所有的字符,忽略其后的所有字符。

返回值:成功执行后返回目标数组指针 dest;

备注:src 和 dest 所指的内存区域不能重叠,且 dest 必须有足够的空间放置 src 所包含的字符串(包含结束符NULL);如果参数 dest 所指的内存空间不够大,可能会造成缓冲溢出(buffer Overflow)的错误情况,在编写程序时请特别留意,或者用strncpy()来取代。

10、strncpy()

头文件:#include <string.h>

函数原型:char * strncpy(char *dest, const char *src, size_t n);

函数说明:strncpy()用来复制字符串的前n个字符;如果src的字符数少于n个,目标字符串就以拷贝的空字符结尾;如果src的字符数有n个或超过n个,就不拷贝空字符;

返回值:返回字符串dest;

备注:src 和 dest 所指的内存区域不能重叠,且 dest 必须有足够的空间放置n个字符;还要注意不拷贝空字符的情况。

11、sprintf()

头文件:#include <stdio.h>

函数原型:int sprintf(char *str, char * format [, argument, ...]);

函数说明:sprintf()函数用于将格式化的数据写入字符串;str为要写入的字符串;format为格式化字符串,与printf()函数相同;argument为变量;sprintf()会根据参数format 字符串来转换并格式化数据,然后将结果复制到参数str 所指的字符串数组,直到出现空字符结束(‘\0‘)为止;

备注:sprintf的作用是将一个格式化的字符串输出到一个目的字符串中,而printf是将一个格式化的字符串输出到屏幕。sprintf的第一个参数应该是目的字符串,如果不指定这个参数,执行过程中出现 "该程序产生非法操作,即将被关闭...."的提示;C语言对数组进行操作时并不检测数组的长度,如果str的长度不够,sprintf()很容易造成缓冲区溢出,带来意想不到的后果,黑客经常利用这个弱点攻击看上去安全的系统。

12、strchr()

头文件:#include <string.h>

函数原型:char * strchr (const char *str, int c);

函数说明:查找某字符在字符串中首次出现的位置;strchr() 将会找出 str 字符串中第一次出现字符 c 的地址,然后将该地址返回;

返回值:如果找到指定的字符则返回该字符所在地址,否则返回 NULL。

备注:字符串 str 的结束标志 ‘\0‘, 也会被纳入检索范围,所以 str 的组后一个字符也可以被定位。

13、strrchr()

头文件:#include <string.h>

函数原型:char * strrchr(const char *str, int c);

函数说明:查找某字符在字符串中最后一次出现的位置;将会找出 str 字符串中最后一次出现字符 c 的地址,然后将该地址返回;

返回值:如果找到就返回该字符最后一次出现的位置,否则返回 NULL。

备注:字符串 str 的结束标志‘\0‘, 也会被纳入检索范围,所以 str 的组后一个字符也可以被定位。

14、strpbrk()

头文件:#include <string.h>

函数原型:char *strpbrk( char *s1, char *s2);

函数说明:检索两个字符串中首个相同字符的位置;strpbrk()从s1的第一个字符向后检索,直到‘\0‘,如果当前字符存在于s2中,那么返回当前字符的地址,并停止检索。

返回值:如果s1、s2含有相同的字符,那么返回指向s1中第一个相同字符的指针,否则返回NULL。

备注:strpbrk()不会对结束符‘\0‘进行检索。

 1 #include<stdio.h>
 2 #include<string.h>
 3 int main(void){
 4     char* s1 = "http://see.xidian.edu.cn/cpp/u/xitong/";
 5     char* s2 = "see";
 6     char* p = strpbrk(s1,s2);
 7     if(p){
 8         printf("The result is: %s\n",p);   
 9     }else{
10         printf("Sorry!\n");
11     }
12     return 0;
13 }
14 
15 结果:
16 The result is: see.xidian.edu.cn/cpp/u/xitong/

15、strstr()

头文件:#include <string.h>

函数原型: char *strstr( char *str, char * substr );

函数说明:用来检索子串在字符串中首次出现的位置;

返回值:返回字符串str中第一次出现子串substr的地址;如果没有检索到子串,则返回NULL。

 1 #include<stdio.h>
 2 #include<string.h>
 3 int main(){
 4     // 也可以改成 char str[] = "http://see.xidian.edu.cn/cpp/u/xitong/";
 5     char *str = "http://see.xidian.edu.cn/cpp/u/xitong/";
 6     char *substr = "see";
 7     char *s = strstr(str, substr);
 8     printf("%s\n", s);
 9     return 0;
10 }
11 
12 结果:
13 see.xidian.edu.cn/cpp/u/xitong/

16、strlen()

头文件:#include <string.h>

函数原型:unsigned int strlen (char *s);

函数说明:计算指定的字符串s 的长度,不包括结束字符‘\0‘;

注意:

一下字符数组,例如
    char str[100] = "http://see.xidian.edu.cn/cpp/u/biaozhunku/";
定义了一个大小为100的字符数组,但是仅有开始的11个字符被初始化了,剩下的都是0,所以 sizeof(str) 等于100,strlen(str) 等于11。

如果字符的个数等于字符数组的大小,那么strlen()的返回值就无法确定了,例如
    char str[6] = "abcxyz";
strlen(str)的返回值将是不确定的。因为str的结尾不是0,strlen()会继续向后检索,直到遇到‘\0‘,而这些区域的内容是不确定的。

strlen() 函数计算的是字符串的实际长度,遇到第一个‘\0‘结束。如果你只定义没有给它赋初值,这个结果是不定的,它会从首地址一直找下去,直到遇到‘\0‘停止。而sizeof返回的是变量声明后所占的内存数,不是实际长度,此外sizeof不是函数,仅仅是一个操作符,strlen()是函数。

17、memchr()

头文件:#include <string.h>

函数原型:void * memchr(const void *s, char c, size_t n);

函数说明:memchr()从头开始搜寻s 所指的内存内容前n 个字节,直到发现第一个值为c 的字节,则返回指向该字节的指针。

返回值:如果找到指定的字节则返回该字节的指针,否则返回NULL。

18、memcmp()

头文件:#include <string.h>

定义函数:int memcmp (const void *s1, const void *s2, size_t n);

函数说明:memcmp()用来比较s1 和s2 所指的内存区间前n 个字符,适用于任何数据类型。

字符串大小的比较是以ASCII 码表上的顺序来决定,次顺序亦为字符的值。memcmp()首先将s1 第一个字符值减去s2 第一个字符的值,若差为0 则再继续比较下个字符,若差值不为0 则将差值返回。例如,字符串"Ac"和"ba"比较则会返回字符‘A‘(65)和‘b‘(98)的差值(-33)。

返回值:若参数s1 和s2 所指的内存内容都完全相同则返回0 值。s1 若大于s2 则返回大于0 的值。s1 若小于s2 则返回小于0 的值。

 1 #include <string.h>
 2 main(){
 3     char *a = "aBcDeF";
 4     char *b = "AbCdEf";
 5     char *c = "aacdef";
 6     char *d = "aBcDeF";
 7     printf("memcmp(a, b):%d\n", memcmp((void*)a, (void*)b, 6));
 8     printf("memcmp(a, c):%d\n", memcmp((void*)a, (void*)c, 6));
 9     printf("memcmp(a, d):%d\n", memcmp((void*)a, (void*)d, 6));
10 }

19、memcpy()

头文件:#include <string.h>

memcpy() 用来复制内存,其原型为:
    void * memcpy ( void * dest, const void * src, size_t num );

memcpy() 会复制 src 所指的内存内容的前 num 个字节到 dest 所指的内存地址上。

memcpy() 并不关心被复制的数据类型,只是逐字节地进行复制,这给函数的使用带来了很大的灵活性,可以面向任何数据类型进行复制。

需要注意的是:

  • dest 指针要分配足够的空间,也即大于等于 num 字节的空间。如果没有分配空间,会出现断错误。
  • dest 和 src 所指的内存空间不能重叠(如果发生了重叠,使用 memmove() 会更加安全)。


与 strcpy() 不同的是,memcpy() 会完整的复制 num 个字节,不会因为遇到“\0”而结束

【返回值】返回指向 dest 的指针。注意返回的指针类型是 void,使用时一般要进行强制类型转换。

20、memmove()

头文件:#include <string.h>

memmove() 用来复制内存内容,其原型为:
    void * memmove(void *dest, const void *src, size_t num);

memmove() 与 memcpy() 类似都是用来复制 src 所指的内存内容前 num 个字节到 dest 所指的地址上。不同的是,memmove() 更为灵活,当src 和 dest 所指的内存区域重叠时,memmove() 仍然可以正确的处理,不过执行效率上会比使用 memcpy() 略慢些。

【返回值】返回指向 dest 的指针。注意返回的指针类型是 void,使用时一般要进行强制类型转换。

21、memset()

头文件:#include <string.h>

memset() 函数用来将指定内存的前n个字节设置为特定的值,其原型为:
    void * memset( void * ptr, int value, size_t num );

参数说明:

  • ptr 为要操作的内存的指针。
  • value 为要设置的值。你既可以向 value 传递 int 类型的值,也可以传递 char 类型的值,int 和 char 可以根据 ASCII 码相互转换
  • num 为 ptr 的前 num 个字节,size_t 就是unsigned int。


【函数说明】memset() 会将 ptr 所指的内存区域的前 num 个字节的值都设置为 value,然后返回指向 ptr 的指针。

memset() 可以将一段内存空间全部设置为特定的值,所以经常用来初始化字符数组。例如:

1 char str[20];
2 memset(str, \0, sizeof(str)-1);

【返回值】返回指向 ptr 的指针。

注意:参数 value 虽声明为 int,但必须是 unsigned char,所以范围在0 到255 之间。

22、strspn()

头文件:#include <string.h>

strspn() 函数用来计算字符串 str 中连续有几个字符都属于字符串 accept,其原型为:
size_t strspn(const char *str, const char * accept);

【函数说明】strspn() 从参数 str 字符串的开头计算连续的字符,而这些字符都完全是 accept 所指字符串中的字符。简单的说,若 strspn() 返回的数值为n,则代表字符串 str 开头连续有 n 个字符都是属于字符串 accept 内的字符。

【返回值】返回字符串 str 开头连续包含字符串 accept 内的字符数目。所以,如果 str 所包含的字符都属于 accept,那么返回 str 的长度;如果 str 的第一个字符不属于 accept,那么返回 0。

注意:检索的字符是区分大小写的。

提示:函数 strcspn() 的含义与 strspn() 相反,可以对比学习。

23、strcspn()

头文件:#inclued<string.h>

strcspn() 用来计算字符串 str 中连续有几个字符都不属于字符串 accept,其原型为:
    int strcspn(char *str, char *accept);

【参数说明】str、accept为要进行查找的两个字符串。

strcspn() 从字符串 str 的开头计算连续的字符,而这些字符都完全不在字符串 accept 中。简单地说,若 strcspn() 返回的数值为 n,则代表字符串 str 开头连续有 n 个字符都不含字符串 accept 中的字符。

【返回值】返回字符串 str 开头连续不含字符串 accept 内的字符数目。

注意:如果 str 中的字符都没有在 accept 中出现,那么将返回 str 的长度;检索的字符是区分大小写的。

提示:函数 strspn() 的含义与 strcspn() 相反,可以对比学习。

24、strtok()

头文件:#include <string.h>

定义函数:char * strtok(char *s, const char *delim);

函数说明:strtok()用来将字符串分割成一个个片段。参数s 指向欲分割的字符串,参数delim 则为分割字符串,当strtok()在参数s 的字符串中发现到参数delim 的分割字符时则会将该字符改为\0 字符。在第一次调用时,strtok()必需给予参数s 字符串,往后的调用则将参数s 设置成NULL。每次调用成功则返回下一个分割后的字符串指针。

返回值:返回下一个分割后的字符串指针,如果已无从分割则返回NULL。

 1 #include <string.h>
 2 main(){
 3     char s[] = "ab-cd : ef;gh :i-jkl;mnop;qrs-tu: vwx-y;z";
 4     char *delim = "-: ";
 5     char *p;
 6     printf("%s ", strtok(s, delim));
 7     while((p = strtok(NULL, delim)))
 8         printf("%s ", p);
 9         printf("\n");
10 }
11 
12 执行结果:
13 ab cd ef;gh i jkl;mnop;qrs tu vwx y;z     //-与:字符已经被\0 字符取代

 

[C] 语言字符串、文件及内存分配函数