序言

C标准库源代码可根据以下2个网址开展查询:The GNU C Library、Welcome to uClibc-ng! - Embedded C library

下列学习小结也是以这两个网址给予的函数库源代码开展学习培训的。

字符串数组有关

strcpy()涵数

库函数:#include <string.h>

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

涵数叙述:将src偏向的字符串数组拷到dest,包含结束符'\0'。字符串数组不可以重合,而且dest有充足的室内空间接受复制的字符串数组。

传参:回到偏向dest储放字符串数组的表针。

函数原型:

char *strcpy(char *dest, const char *src)
{
	char *dst = dest;

	while ((*dst = *src) != '\0') {
		src  ;
		dst  ;
	}

	return dest;
}

能够 看得出,涵数中并不会查验dest的室内空间尺寸,只能复制字符串数组直至碰到src字符串的结束符'\0',因而dest的室内空间尺寸必须 客户确保。

功能测试一:dest室内空间超过src偏向的字符串数组数量。

#include <stdio.h>
#include <string.h>

int main(void)
{
    char *str_original = "0123456789";
    char buf_dest[12] = {0};
    char *ret = NULL;
    int i = 0;

    for (i = 0; i < sizeof(buf_dest); i  )
        buf_dest[i] = 1;

    printf("dest:0x%x\n", buf_dest);
    ret = strcpy(buf_dest, str_original);
    printf(" ret:0x%x\n", ret);
    for (i = 0; i < sizeof(buf_dest); i  )
        printf("%d ", buf_dest[i]);
    printf("\n");

    return 0;
}

编译程序,运作結果:

$ ./a.out 
dest:0xca8e26c0
 ret:0xca8e26c0
48 49 50 51 52 53 54 55 56 57 0 1 

能够 看得出,字符串数组复制的情况下会复制字符串数组结束符'\0'。

功能测试二:dest室内空间低于src偏向的字符串数组数量(不正确使用方法)。

#include <stdio.h>
#include <string.h>

int main(void)
{
    char *str_original = "0123456789";
    char buf_dest[5] = {0};
    char *ret = NULL;
    int i = 0;

    for (i = 0; i < sizeof(buf_dest); i  )
        buf_dest[i] = 1;

    printf("dest:0x%x\n", buf_dest);
    ret = strcpy(buf_dest, str_original);
    printf(" ret:0x%x\n", ret);
    printf("%s\n", buf_dest);

    return 0;
}

编译程序,运作:

$ ./a.out 
dest:0xe31dee10
 ret:0xe31dee10
01234567

因为dest沒有以'\0'末尾,因而printf打印出的信息内容是不正确的,浏览的內容早已超出了dest的室内空间。

功能测试三:运行内存重合

参照blog:strcpy涵数的完成 - Norcy - 博客园 (cnblogs.com)

#include <stdio.h>
#include <string.h>

int main(void)
{
    char str[12] = "hello";
    strcpy(str   1, str);  //存有段错误
    printf("%s\n", str);

    return 0;
}
#include <stdio.h>
#include <string.h>

int main(void)
{
    char str[12] = "hello";

    strcpy(str, str 1);
    printf("%s\n", str);   //输出打印ello

    return 0;
}

第一种状况:strcpy(str 1, str),这类状况下dest偏向'e',而src第一个标识符为'h',当复制的情况下,'\0'结束符会被遮盖掉,造成一直复制,深陷无限循环。

第二种状况:strcpy(str, str 1),这类状况下,仅复制"ello"。

strncpy()涵数

库函数:#include <string.h>

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

涵数叙述:作用和strcpy涵数相近,但仅复制src的n字节数给dest。此外假如n字节数中沒有结束符'\0',那麼复制完后,dest中是不容易有结束符的,这一必须 留意。假如src的长短低于n字节数,可能在复制src字符串以后再次复制结束符给dest,直至达到n字节数。

函数原型:

char *strncpy (char *s1, const char *s2, size_t n)
{
    reg_char c;
    char *s = s1;

    --s1;

    if (n >= 4) 
    {
        size_t n4 = n >> 2;
        for ( ; ; )
        {
            c = *s2  ;
            *  s1 = c;
            if (c == '\0')
                break;
            c = *s2  ;
            *  s1 = c;
            if (c == '\0')
                break;
            c = *s2  ;
            *  s1 = c;
            if (c == '\0')
                break;
            c = *s2  ;
            *  s1 = c;
            if (c == '\0')
                break;
            if (--n4 == 0)
                goto last_chars;
        }
        n = n - (s1 - s) - 1;
        if (n == 0)
            return s;
        goto zero_fill;
    }

last_chars:
    n &= 3;
    if (n == 0)
        return s;

    do
    {
        c = *s2  ;
        *  s1 = c;
        if (--n == 0)
            return s;
    } while (c != '\0');

zero_fill:
    do
        *  s1 = '\0';
    while (--n > 0);

    return s;
}

功能测试一:src字符串长短超过n,且前n字符中存有结束符,则只能拷到第一个结束符时就完毕复制。

#include <stdio.h>
#include <string.h>

int main(void)
{
    char str_original[] = {'a', '\0', 'b', '\0', 'c', 'd', 'e', '\0'};
    char str_dest[8] = {0};
    int i = 0;

    strncpy(str_dest, str_original, 8);
    for (i = 0; i < 12; i  )
        printf("%d ", str_dest[i]);
    printf("\n");

    return 0;
}

编译程序,运作:

$ ./a.out    
97 0 0 0 0 0 0 0 

功能测试二:src字符串长短超过n,且前n字符中不会有结束符,则会复制n字符。解决这类状况,一般必须 自身去在dest结尾加上一个结束符。

#include <stdio.h>
#include <string.h>

int main(void)
{
    char str_original[] = {'a', 'b', 'c', 'd', 'e', 'f', '\0'};
    char str_dest[5] = {0};
    int i = 0;

    strncpy(str_dest, str_original, 5);
    for (i = 0; i < 5; i  )
        printf("%d ", str_dest[i]);
    printf("\n");

    return 0;
}

编译程序,运作:

$ ./a.out 
97 98 99 100 101 

功能测试三:src字符串长短低于n,可能在复制src字符串以后再次复制结束符给dest,直至达到n字节数。

#include <stdio.h>
#include <string.h>

int main(void)
{
    char str_original[] = {'a', 'b', 'c', 'd', 'e', 'f', '\0'};
    char str_dest[12] = {0};
    int i = 0;

    for (i = 0; i < 12; i  )
        str_dest[i] = 1;

    strncpy(str_dest, str_original, 12);
    for (i = 0; i < 12; i  )
        printf("%d ", str_dest[i]);
    printf("\n");

    return 0;
}

编译程序,运作:

$ ./a.out    
97 98 99 100 101 102 0 0 0 0 0 0 

评论(0条)

刀客源码 游客评论