[置顶] 一些常用函数,as:strnstr,memchr。。。。。

时间:2022-05-05 20:34:28

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  逆向 寻找字符 并且返回 从指定字符开始的字符串


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

函数名: 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);
}

}