【C语言】字符串与指针

字符串与指针

字符串的两种存储形式

C语言中并没有字符串这个特定类型,而是以字符数组的形式来存储和处理字符串,这种字符数组必须以空字符\0结尾,因此,也将这种特定字符数组称为C风格字符串。

  • 字符数组形式:char str[20]
  • 字符指针形式:char *pc
char str[20] = "hello";
str[0] = 'H';      // str是一个字符数组,字符串中的每个字符逐个存放,可以随意修改
str = "world";     // 但是str本身是一个常量,不能改变str(的指向)。

char *pc = "hello";
pc[0] = '';        // pc是一个字符指针,如果指向的是常量区的字符串,这个字符串不能修改,只能访问
pc = "world";     //但是pc本身的指向可以修改。

字符串输入

gets()在C++14中已被彻底废弃。

fgets

char *fgets(char *s, int size, FILE *stream);
/* fgets() reads in at most one less than size characters from stream and stores them into the buffer pointed to by s.  Reading stops after an EOF or a newline.  If a newline is read, it is stored into the buffer.  A terminating null byte ('\0') is stored after the  last  character in the buffer. */
// fgets遇到换行会将换行也读入
// fgets最多能输入size-1个字符,因为最后一位一定要留给\0

scanf

char str[10];
scanf("%s", &str);
// scanf不会读取换行符,换行符会被留在缓冲区中,并且scanf不会在最后加\0

strlen

size_t strlen(const char *s);
// 计算字符串 **str** 的长度,直到空结束字符,但不包括\0

实现strlen

// 遍历统计
int mystrlen1(const char *str)
{
    int res = 0;
    while(*str != '\0')
    {
        ++str;
        ++res;
    }
    return res;
}

// 终点减起点
int mystrlen2(const char *str)
{
    const char *begin = str;
    const char *end = str;
    while(*end != '\0') ++end;
    return end - begin;
}
  • strcpy将src拷贝到dst(包括\0)
  • strncpy将src前n个字符拷贝到dst(最多拷贝n个)
    • strlen(src) >= n, dst没有\0结尾, 拷贝n个
    • strlen(src) + 1 <= n, dst有\0结尾, 但只会拷贝strlen(src)+1个
  • strcat将src拼接到dst尾(覆盖dst尾的\0), 拼接完后再在dst尾添一个\0
  • strncat将src前n个字符拼接到dst尾
    • strlen(src) >= n, 将src的前n个字符拼接到dst尾,此时src可以没有\0结尾
    • strlen(src) + 1 <= n, 将src的所有字符拼接到dst尾,此时src要有\0结尾

strcpy strncpy

char *strcpy(char *dest, const char *src);
/* The  strcpy() function copies the string pointed to by src, including the terminating null byte ('\0'), to the buffer pointed to by dest.  The strings may not overlap, and the destination string dest must be large enough to receive the copy.  Beware of buffer overruns!  (See BUGS.) */

char *strncpy(char *dest, const char *src, size_t n);
/* The  strncpy()  function is similar, except that at most n bytes of src are copied. Warning: If there is no null byte among the first n bytes of src, the string placed in dest will not be null-terminated. 
If the length of src is less than n, strncpy() writes additional null bytes to dest to ensure that a total of n bytes are  written. */

实现strcpy

char *mystrcpy(char *dst, const char *src)
{
    char *res = dst;
    while(*src != '\0')
        *dst++ = *src++;
    *dst = '\0';     // 将src中的\0也复制到dst中
    return res;
}

实现strncpy

char *strncpy(char *dest, const char *src, size_t n)
{
    size_t i;
    for (i = 0; i < n && src[i] != '\0'; i++)
        dest[i] = src[i];
    for ( ; i < n; i++)
        dest[i] = '\0';

    return dest;
}

strcat strncat

char *strcat(char *dest, const char *src);
/*  The  strcat()  function  appends  the  src string to the dest string, overwriting the terminating null byte ('\0') at the end of dest, and then adds a terminating null byte.  
The strings may not overlap, and the dest string must have enough space for the result.  
If dest is not large enough, program behavior is unpredictable; buffer overruns are a favorite avenue for attacking secure programs.  */

char *strncat(char *dest, const char *src, size_t n);
/* The strncat() function is similar, except that
       *  it will use at most n bytes from src;
       *  src does not need to be null-terminated if it contains n or more bytes.
As with strcat(), the resulting string in dest is always null-terminated. If src contains n or more bytes, strncat() writes n+1 bytes to dest (n from src plus the terminating null byte). Therefore, thesize of dest must be at least strlen(dest)+n+1.    */

实现strcat

char *mystrcat(char *dst, const char *src)
{
    char *res = dst;
    while(*dst != '\0') ++dst;  // 注意这个++不能写进while循环条件里,注意一下
    while(*src != '\0') *dst++ = *src++;
    *dst = '\0';

    return res;
}

实现strncat

char *mystrncat(char *dest, const char *src, size_t n)
{
    size_t dest_len = strlen(dest);
    size_t i;

    for (i = 0 ; i < n && src[i] != '\0' ; i++)
        dest[dest_len + i] = src[i];
    dest[dest_len + i] = '\0';

    return dest;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值