C常用函数

来源:互联网 发布:中信炒股软件下载 编辑:程序博客网 时间:2024/04/27 23:29

C语言有些常用函数,本文会逐步增加学习过程中用到的这些C函数。

1. char* strcpy(char* destStr, const char* srcStr)

    在string.h中定义。将srcStr的每个字符逐个拷贝至destStr。 

    与“=”不同,“=”会将destStr赋值为srcStr,即两个指针指向同一地址。

    对比:

          (1)string.h中  char *strncpy(char *dest, const char *src, int n) 最多拷贝n个字符。复制字符串src中的内容(字符,数字、汉字....)到字符串dest中,复制多少由size_tn的值决定。如果src的前n个字节不含NULL字符,则结果不会以NULL字符结束。如果n<src的长度,只是将src的前n个字符复制到dest的前n个字符,不自动添加'\0',也就是结果dest不包括'\0',需要再手动添加一个'\0'。如果src的长度小于n个字节,则以NULL填充dest直到复制完n个字节。src和dest所指内存区域不可以重叠且dest必须有足够的空间来容纳src的字符长度+'\0; 复制src时遇到'\0'会停止。

          (2) void *memcpy(void *dest, const void *src, size_t n); 从源src所指的内存地址的起始位置开始拷贝n个字节到目标dest所指的内存地址的起始位置中。

            详解:

                         

1. strcpy函数

   strcpy提供了字符串的复制。即strcpy只用于字符串复制,并且它不仅复制字符串内容之外,还会复制字符串的结束符。

   函数原型及实现:

[c-sharp] view plain copy
  1. char* strcpy(char* strDst, const char* strSrc)      
  2. {  
  3.     assert((strDst != NULL) && (strSrc != NULL));  
  4.     char* address = strDst;   
  5.     while((*strDst++ = *strSrc++) != '/0');  
  6.     return address;  
  7.   }  
  

 

  注意:

  1. 该函数会连同字符串的结束字符'/0'一起拷贝到字符数组中,故字符数组的长度应该至少是字符串的长度加1。

  例:

  char str[] = "123456";

  这里str是一个字符数组,它存放了一个字符串"123456",由于字符串还有一个结束符"/0",所以此数组的长度为7而不是6。

 

   char *str = "123456";  //该字符串的长度为6(字符串以字符'/0'结尾,不计入字符串长度)

   char   dst[7];   //字符数组的长度必须至少为字符长度加1,如6+1=7。

   strcpy(dst, str);

  2. 该函数会拷贝字符串的内容直至遇到第一个字符值为0的字符(第一个字符值为0的字符也会被拷贝),故如果一个字符串或字符数组含

     有大量的值为0的数据,则不宜用该函数进行拷贝操作,可用memcpy函数。

 

2. memcpy函数

   memcpy提供了一般内存的复制。即memcpy对于需要复制的内容没有限制,因此用途更广。

   该函数将一个大小为size的内存段的值拷贝到另一内存段中。

   其实现如下:

[c-sharp] view plain copy
  1. void *memcpy(void *memTo, const void *memFrom, size_t size)     
  2. {  
  3.     assert((memTo != NULL) && (memFrom != NULL)); //memTo和memFrom必须有效  
  4.     char *tempFrom = (char *)memFrom;             //保存memFrom首地址  
  5.      char *tempTo = (char *)memTo;                  //保存memTo首地址  
  6.     while(size -- > 0)                //循环size次,复制memFrom的值到memTo中  
  7.         *tempTo++ = *tempFrom++ ;   
  8.     return memTo;   
  9. }  
  

 

 

3. strcpy与memcpy的区别

  3.1 复制的内容不同。

     strcpy只能复制字符串,而memcpy可以复制任意内容,例如字符数组、整型、结构体、类等。

  3.2 复制的方法不同。

     strcpy不需要指定长度,它遇到字符串结束符"/0"便结束。memcpy则是根据其第3个参数决定复制的长度。

  3.3 用途不同。

     通常在复制字符串时用strcpy,而需要复制其他类型数据时则一般用memcpy。

 

4. strncpy

strncpy的实现如下

[c-sharp] view plain copy
  1. char *strncpy(char *dst, const char *src, size_t count)  
  2. {  
  3.         assert((dst != NULL) && (src != NULL));  
  4.         char *tmp = dst;  
  5.   
  6.         while (count-- && (*dst++ = *src++) != '/0')  
  7.         {  
  8.                 /* nothing */;  
  9.         }  
  10.   
  11.         return tmp;  
  12. }  

 

该函数用于拷贝count个字符。

 

注意:

1. count一定要小于dst的大小。

2.调用完该函数后一定要加上一句:dst[count] = '/0';否则不安全,如strlen等函数要求参数必须是以'/0'结尾的字符串

   因为当count小于src的大小时,src的结束字符'/0'并不会被拷贝,故应该为dst加上一个结束符。

例:

[c-sharp] view plain copy
  1. char *str = "123456";  
  2.   
  3. char dst[7];  
  4.   
  5. int count = 6;  
  6.   
  7. strncpy(dst, str, count);  //count=6一定要小于dst的长度(7)。  
  8.   
  9. dst[count] = '/0'; 



2. int strcmp(const char* str1, const char* str2)

     逐个字符比较str1和str2.   (str1== str2只比较两个指针)

     result = 0  表示str1与str2相等

     result > 0 表示str1 > str2

     result < 0 表示str1 < str2


2. size_t write(int fd, const void* buf, size_t bytes)

    把缓冲区buf的前bytes个字节写入与fd关联的文件中。

    对fd, 0表示标准输入,1:标准输出,2:标准输入。 普通的文件描述符为其他值。

    例如: write(1, "Here is write function", 23);


3. size_t read(int fd, void * buf, size_t bytes)

     从fd关联的文件中读取bytes个字节的数据,并放至buf中。


4. int printf(const char* format, ...)

    将格式化数据送至缓冲区。

     缓冲区刷新方式:1.显示刷新 fflush 2. 数据中含有/r或 /n 3缓冲区满  4.取缓冲区数据,如scanf


5. 字符指针与字符数组

     const char* pt = "Hello";

     这种写法,字符串被存储在静态存储区,整个程序都可以使用。 如果不加const, 编译器报错:conversion from string literal to 'char *' is deprecated.

     char pt[] = “Hello";

     这种写法,字符串存储在栈上。可修改。


6. stdin  与 STDIN_FILENO

    stdin 类型是FILE*; STDIN_FILENO是int类型,值为0;

    另外,STDOUT_FILENO值为1; STDERROR_FILENO 值为2;

    FILE* 多用于fread(), fwrite(),  fclose(), fget()等;

    STDIN_FILENO等多用于read(), write()等。


7. int atom(const char* ch)

    将字符转化为整数


8. void* memset(void* s, int ch, size_t size)

    将s开始的size个地址内容用ch代替。返回s


9. int snprintf(char *str, size_t size, const char *format, ...) 

       将可变个参数(...)按照format格式化成字符串,然后将其复制到str中
      (1) 如果格式化后的字符串长度 < size,则将此字符串全部复制到str中,并给其后添加一个字符串结束符('\0');
      (2) 如果格式化后的字符串长度 >= size,则只将其中的(size-1)个字符复制到str中,并给其后添加一个字符串结束符('\0'),返回值为欲写入的字符串长度。

       对比 int sprintf(char *str, const char *format, ...):

          因为C语言在进行字符串操作时不检查字符串的空间是否够大,所以可能会出现数组越界而导致程序崩溃的问题。即使碰巧,程序没有出错,也不要这么用,因为早晚会出错。所以一定要在调用sprintf之前分配足够大的空间给buf。

10. int   access(const   char   *filename,   int   amode);
       amode参数为0时表示检查文件的存在性,如果文件存在,返回0,不存在,返回-1。
     这个函数还可以检查其它文件属性:
     06     检查读写权限
     04     检查读权限
     02     检查写权限
     01     检查执行权限
     00     检查文件的存在性

11 time()

      直接看代码:

             time_t  time;

             time(&time); //  等价time = time(NULL);

            (1) printf("now time is %s", ctime(&time));  // Wed Mar 23 16:42:13 2016

            (2)struct tm *localtime(const time_t *clock)    可以用于定制格式

                struct tm
                 {
                     int tm_sec;            /* Seconds.    [0-60] (1 leap second) */
                     int tm_min;            /* Minutes.    [0-59] */
                     int tm_hour;            /* Hours.    [0-23] */
                     int tm_mday;            /* Day.        [1-31] */
                     int tm_mon;            /* Month.    [0-11] */
                     int tm_year;            /* Year    - 1900.  */
                     int tm_wday;            /* Day of week.    [0-6] */
                     int tm_yday;            /* Days in year.[0-365]    */
                     int tm_isdst;            /* DST.        [-1/0/1]*/

                    # ifdef    __USE_MISC
                    long int tm_gmtoff;        /* Seconds east of UTC.  */
                    const char *tm_zone;        /* Timezone abbreviation.  */
                    # else
                    long int __tm_gmtoff;        /* Seconds east of UTC.  */
                    const char *__tm_zone;    /* Timezone abbreviation.  */
                     # endif
                    };

                    接上面代码:

                     struct tm* sTm =  localtime(&time);

                     char buf[256];

                      bzero(buf, 256);

                      string strTime;

                      snprintf(strTime, 256, "%04-%02-%02 %02:%02:%02",

                                                               1900+sTm.tm_year,

                                                               1+sTm.tm_mon,

                                                               sTm.tm_mday,

                                                                sTm.hour, sTm.min, sTm.sec);    //  2016-03-23 14:02:22


12.

       size_t read(int files, const void* buf, size_t nbytes); 从files关联的文件中中读取nbytes个字节,写入数据区buf中,返回实际读取的字节数

        size_t fread(const void* prt, size_t size,  size_t nitems, FILE *stream);

        char *fget(char *s, int n, FILE *stream); 从输入流读取一个字符串。 最多传输n-1个字符,因为可能自动加\0。

         char *get(char *s). 从标准输入中读取字符串。 可能会溢出,所以尽量使用fgets


13 回车与换行

     \r' ASCII码为13 是回车,将当前位置移到本行头
     printf("xx\ryy\n"); xx将不会被输出
    '\n'ASCII码为10 是换行,将当前位置移到下一行
    printf("xx\nyy\n");将会输出两行即














0 0