一些常用函数,as:strnstr,memchr。。。。。
Posted tiny丶
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了一些常用函数,as:strnstr,memchr。。。。。相关的知识,希望对你有一定的参考价值。
1‘ strnstr
//
从 s 串 中 找到 子串 find 并且 返回 find 在s 中的 位置
slen表示find 的长度!。。
1 #include<stdio.h>
2 #include<string.h>
3 char *strnstr( char *s, char *find, size_t slen)
4
5 char c, sc;
6 size_t len;
7
8 if ((c = *find++) != '\\0')
9 len = strlen(s);
10 do
11 do
12 if (len-- < 1 || (sc = *s++) == '\\0')
13 return (NULL);
14 printf("sc:%c,len=%d\\n",sc,len);
15 while (sc != c);
16 if (slen > len)
17 return (NULL);
18 while (strncmp(s, find, slen-1) != 0);
19 s--;
20
21 return ((char *)s);
22
23
24 int main()
25
26 char *sp="woaichenpeiqing";
27 char *ds="chen";
28 printf("%s\\n",strnstr(sp,ds,strlen(ds)));
29 return 0;
30
~
2、memchr
原型:extern void *memchr(const void *buf, int ch, size_t count); 用法:#include <string.h> 功能:从buf所指内存区域的前count个 字节查找 字符ch。 说明:当第一次遇到字符ch时停止查找。如果成功,返回指向字符ch的 指针;否则返回NULL。 举例: // memchr.c #include <syslib.h> #include <string.h> main() char *s="Hello, Programmers!"; char *p; clrscr(); p=memchr(s,'P',strlen(s)); //p=(char *)memchr(s,'P',sizeof(s)); //s是一个指向char的指针,而任何指针都是个一个4字节的数,在这里应//该是要说明搜索整个字符串的长度,所以应该用strlen(s)
if(p) printf("%s",p); else printf("Not Found!"); getchar(); return 0; ------------------------------------------------------------
3、strchr
strchr函数原型:extern char *strchr(const char *s,char c);查找字符串s中首次出现字符c的位置。
1
2
3
4
5
6
7
8
char* strchr(char* s,char c)
while(*s != '\\0' && *s != c)
++s;
return *s == c ?s:NULL;
ps: 与之 相对应的 函数 strrchr 逆向 寻找字符 并且返回 从指定字符开始的字符串
4·snprintf()
int snprintf(char *str, size_t size, const char *format, ...);
<span style="font-size:18px;">将可变个参数(...)按照format格式化成字符串,然后将其复制到str中
(1) 如果格式化后的字符串长度 < size,则将此字符串全部复制到str中,并给其后添加一个字符串结束符('\\0');
(2) 如果格式化后的字符串长度 >= size,则只将其中的(size-1)个字符复制到str中,并给其后添加一个字符串结束符('\\0'),返回值为格式化后的字符串的长度。
char a[20];
i = snprintf(a, 9, "%012d", 12345);
printf("i = %d, a = %s", i, a);
输出为:i = 12, a = 00000001</span>
5\\ strdup
<span style="font-size:18px;">将可变个参数(...)按照format格式化成字符串,然后将其复制到str中
(1) 如果格式化后的字符串长度 < size,则将此字符串全部复制到str中,并给其后添加一个字符串结束符('\\0');
(2) 如果格式化后的字符串长度 >= size,则只将其中的(size-1)个字符复制到str中,并给其后添加一个字符串结束符('\\0'),返回值为格式化后的字符串的长度。
char a[20];
i = snprintf(a, 9, "%012d", 12345);
printf("i = %d, a = %s", i, a);
输出为:i = 12, a = 00000001</span>
函数名: strdup
功 能: 将串拷贝到新建的位置处
用 法: char *strdup(char *str);
这个函数在linux的man手册里解释为:
The strdup() function returns a pointer toa new string which is a
duplicate of the string s. Memory for thenew string is obtained with
malloc(3), and can be freed with free(3).
The strndup() function is similar, but onlycopies at most n charac-
ters. If s is longer than n, only ncharacters are copied, and a termi-
nating NUL is added.
strdup函数原型:
strdup()主要是拷贝字符串s的一个副本,由函数返回值返回,这个副本有自己的内存空间,和s不相干。strdup函数复制一个字符串,使用完后要记得删除在函数中动态申请的内存,strdup函数的参数不能为NULL,一旦为NULL,就会报段错误,因为该函数包括了strlen函数,而该函数参数不能是NULL。
strdup的工作原理:
char * __strdup (const char *s)
size_t len =strlen (s) + 1;
void *new =malloc (len);
if (new == NULL)
return NULL;
return (char *)memcpy (new, s, len);
实例1:
C/C++ code
#include <stdio.h>
#include <string.h>
#include <alloc.h>
int main(void)
char *dup_str,*string = "abcde";
dup_str =strdup(string);
printf("%s\\n", dup_str);free(dup_str); return 0;
实例2:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
unsigned int Test()
charbuf[]="Hello,World!";
char* pb =strndup(buf,strlen(buf));
return (unsignedint)(pb);
int main()
unsigned int pch= Test();
printf("Testing:%s\\n",(char*)pch);
free((void*)pch);
return 0;
在Test函数里使用strndup而出了Test函数仍可以操作这段内存,并且可以释放。
由这个问题而延伸出来的问题就是,如何让函数得到的内存数据传出函数但仍可用。
解决方法目前本人只想到两个: 一个外部变量,如传递一个内存块指针给函数,但这种做法就是你得传递足够的内存,也就是你不能事先知道这个函数到底要多大的BUFFER。
另一种方法就是在函数内部申请static变量,当然这也是全局区的变量,但这种做法的缺点就是,当函数多次运行时,static变量里面的数据会被覆盖。这种类型的另一个方法就是使用全局变量,但这和使用static变量很相同,不同的是全局变量可以操作控制,而static变量如果不把它传出函数,就不可对它操作控制了。另一类方法就是上面所述的,利用堆里的内存来实现,但存在危险。strdup是从堆中分配空间的!strdup调用了malloc,所以它需要释放!对于堆栈:堆是由程序员来管理的,比如说new,malloc等等都是在堆上分配的!
栈是由编译器来管理的。
6、remove 头文件:#include <stdio.h>
定义函数:int remove(const char * pathname);
函数说明:remove()会删除参数pathname 指定的文件. 如果参数pathname 为一文件, 则调用unlink()处理,若参数pathname 为一目录, 则调用rmdir()来处理. 请参考unlink()与rmdir().
返回值:成功则返回0, 失败则返回-1, 错误原因存于errno.
7、rename
#include <stdio.h> int rename(const char *oldname, const char *newname); 函数说明 (1) 如果oldname为一个文件而不是目录,那么为该文件更名。在这种情况下,如果newname作为一个目录已存在,则它不能 重命名一个目录。如果newname已存在,而且不是一个目录,则先将其删除然后将oldname更名为newname。对oldname所在目录以及newname所在的目录,调用进程必须具有写许可权,因为将更改这两个目录。 (2) 如若oldname为一个目录,那么为该目录更名。如果newname已存在,则它必须是一个目录,而且该目录应当是空目录(空目录指的是该目录中只有. 和.. 项)。如果newname存在(而且是一个空目录),则先将其删除,然后将oldname更名为newname。另外,当为一个目录更名时,newname不能包含oldname作为其路径前缀。例如,不能将/usr更名为/usr/foo/testdir,因为老名字( /usr/foo)是新名字的路径前缀,因而不能将其删除。 (3) 作为一个特例,如果oldname和newname引用同一文件,则函数不做任何更改而成功返回。 返回值 执行成功则返回0,失败返回-1,错误原因存于errno
8、mmap
mmap将一个文件或者其它对象映射进内存。文件被映射到多个页上,如果文件的大小不是所有页的大小之和,最后一个页不被使用的空间将会清零。
#include <sys/mman.h> void *mmap(void *start, size_t size, int prot, int flags, int fd, off_t offset); int munmap(void *start, size_t size);
条件:
mmap()必须以PAGE_SIZE()为单位进行映射,而内存也只能以页为单位进行 映射 ,若要映射非PAGE_SIZE整数倍的地址范围,要先进行内存对齐,强行以PAGE_SIZE的倍数大小进行映射。start:映射区的开始地址,设置为0时表示由系统决定映射区的起始地址。 length:映射区的长度。//长度单位是 以字节为单位,不足一内存页按一内存页处理 prot:期望的内存保护标志,不能与文件的打开模式冲突。是以下的某个值,可以通过or运算合理地组合在一起 PROT_EXEC //页内容可以被执行 PROT_READ //页内容可以被读取 PROT_WRITE //页可以被写入 PROT_NONE //页不可访问 flags:指定映射对象的类型,映射选项和映射页是否可以共享。它的值可以是一个或者多个以下位的组合体 MAP_FIXED //使用指定的映射起始地址,如果由start和len参数指定的内存区重叠于现存的映射空间,重叠部分将会被丢弃。如果指定的起始地址不可用,操作将会失败。并且起始地址必须落在页的边界上。 MAP_SHARED //与其它所有映射这个对象的进程共享映射空间。对共享区的写入,相当于输出到文件。直到msync()或者 munmap()被调用,文件实际上不会被更新。 MAP_PRIVATE //建立一个写入时拷贝的私有映射。内存区域的写入不会影响到原文件。这个标志和以上标志是互斥的,只能使用其中一个。 MAP_DENYWRITE //这个标志被忽略。 MAP_EXECUTABLE //同上 MAP_NORESERVE //不要为这个映射保留交换空间。当交换空间被保留,对映射区修改的可能会得到保证。当交换空间不被保留,同时 内存不足,对映射区的修改会引起段违例信号。 MAP_LOCKED //锁定映射区的页面,从而防止页面被交换出内存。 MAP_GROWSDOWN //用于堆栈,告诉 内核VM系统,映射区可以向下扩展。 MAP_ANONYMOUS //匿名映射,映射区不与任何文件关联。 MAP_ANON //MAP_ANONYMOUS的别称,不再被使用。 MAP_FILE //兼容标志,被忽略。 MAP_32BIT //将映射区放在进程 地址空间的低2GB,MAP_FIXED指定时会被忽略。当前这个标志只在x86-64平台上得到支持。 MAP_POPULATE //为文件映射通过预读的方式准备好页表。随后对映射区的访问不会被页违例阻塞。 MAP_NONBLOCK //仅和MAP_POPULATE一起使用时才有意义。不执行预读,只为已存在于内存中的页面建立 页表入口。 fd:有效的 文件描述词。一般是由open()函数返回,其值也可以设置为-1,此时需要指定flags参数中的MAP_ANON,表明进行的是匿名映射。 offset:被映射对象内容的起点。 http://blog.csdn.net/vevenlcf/article/details/25893373
9、memcmp (我去 我看成了 memcpy) 靠了 int memcmp(const void *buf1, const void *buf2, unsigned int count);
#include <string.h>或#include<memory.h>
当buf1<buf2时,返回值<0 当buf1=buf2时,返回值=0 当buf1>buf2时,返回值>0 该函数是按 字节比较的。 例如: s1,s2为字符串时候memcmp(s1,s2,1)就是比较s1和s2的第一个 字节的ascII码值; memcmp(s1,s2,n)就是比较s1和s2的前n个 字节的ascII码值; 如:char *s1="abc"; char *s2="acd"; int r=memcmp(s1,s2,3); 就是比较s1和s2的前3个字节,第一个字节相等,第二个字节比较中大小已经确定,不必继续比较第三字节了。所以r=-1.
#include<string.h>
#include<stdio.h>
main()
char *s1="Hello, Programmers!";
char *s2="Hello, programmers!";
int r;
r=memcmp(s1,s2,strlen(s1));
if(!r)
printf("s1 and s2 are identical\\n"); /*s1等于s2*/
else if(r<0)
printf("s1 is less than s2\\n"); /*s1小于s2*/
else
printf("s1 is greater than s2\\n"); /*s1大于s2*/
return 0;
10、access && mkdir
#include<sys/stat.h>
#include<sys/types.h>
#include<sys/errno.h>
#include<unistd.h>
#define TMP_LOG_FILE_DIR "/tmp/lcf/log"
int main()
/* char *ac_dir = "/tmp/log";
if(access(ac_dir, F_OK)==-1)
printf("file not sucess\\n");
printf("tmp/lcf have exits\\n");
char *dir = "/tmp/log/";
if(mkdir(dir, 655) != 0)
if(errno != EEXIST)
perror("mkdir");
exit(-1);
*/
if(access(TMP_LOG_FILE_DIR, F_OK)==-1)
printf("failed\\n");
char dir_log[126]='\\0';
snprintf(dir_log, 126, "mkdir -p %s", TMP_LOG_FILE_DIR);
system(dir_log);
以上是关于一些常用函数,as:strnstr,memchr。。。。。的主要内容,如果未能解决你的问题,请参考以下文章