Bootstrap

字符函数和字符串函数2

接续上文,我们讲了求字符串长度的
strlen
还有长度不受限制的字符串函数
strcpy
strcat
strcmp

那么本篇我们就继续来讲长度受限制的字符串函数。

strncpy
strncat
strncmp

strncpy

strncpy 是 C 语言标准库中的一个函数,用于将一个字符串复制到另一个字符串中,但允许指定最大复制长度,从而避免缓冲区溢出。与 strcpy 不同,strncpy 提供了一种更安全的方式来复制字符串。

看到他是不是自然就想起了我们上一篇文章看到过的strcpy,可以说strncpy就是他的升级版,plus版本,通过指定复制的长度,弥补了strcpy会超出空间的缺陷。

char *strncpy(char *dest, const char *src, size_t n);

dest:指向目标字符串的指针,即要将源字符串复制到的位置。
src:指向源字符串的指针,即要被复制的字符串。
n:最多复制的字符数(不包括结尾的空字符 \0)。

拷贝n个字符从源字符串到目标空间。
如果源字符串的长度小于n,则拷贝完源字符串之后,在目标的后边追加0,直到n个。

但是相反的,如果 src 的长度大于或等于 n,strncpy 只会复制前 n 个字符,并且不会添加结尾的空字符 \0。因此,你需要手动确保 dest 以 \0 结尾。

怎么做呢,看一下代码就知道了

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

int main() {
    char src[] = "Hello, World!";
    char dest[50];
    size_t n = sizeof(dest) - 1;  // 确保留有空间给结尾的空字符

    // 使用 strncpy 并确保添加结尾的空字符
    strncpy(dest, src, n);
    dest[n] = '\0';  // 手动添加结尾的空字符

    printf("Source: %s\n", src);      // 输出: Source: Hello, World!
    printf("Destination: %s\n", dest); // 输出: Destination: Hello, World!

    return 0;
}

没错就是这么简单,直接赋值\0就可以了。

strncat

char *strncat(char *dest, const char *src, size_t n)

没错,如你所想,strncat也是strcat的升级版,更安全版。

dest:指向目标字符串的指针,即要将源字符串追加到的位置。
src:指向源字符串的指针,即要被追加的字符串。
n:最多追加的字符数(不包括结尾的空字符 \0)。

但是和strncpy不一样的是:strncat 会找到 dest 中的第一个空字符 \0,然后从该位置开始追加 src 中的最多 n 个字符。
如果 src 的长度小于 n,strncat 会追加整个 src 字符串,并添加结尾的空字符 \0。
如果 src 的长度大于或等于 n,strncat 只会追加前 n 个字符,并添加结尾的空字符 \0

会自动追加,省时省力,下面放一下使用代码

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

int main() {
    char dest[50] = "Hello, ";
    const char *src = "World!";
    size_t n = 5;  // 最多追加 5 个字符

    // 使用 strncat 并确保不会超出缓冲区
    strncat(dest, src, n);

    printf("Result: %s\n", dest);  // 输出: Result: Hello, World

    return 0;
}

strncmp

和前两个一样,也可以指定比较的长度。所以这里就放一下代码,相信大家去试着运行就会懂了,

/* strncmp example */
#include <stdio.h>
#include <string.h>
int main ()
{
  char str[][5] = { "R2D2" , "C3PO" , "R2A6" };
  int n;
  puts ("Looking for R2 astromech droids...");
  for (n=0 ; n<3 ; n++)
  if (strncmp (str[n],"R2xx",2) == 0)
 {
    printf ("found %s\n",str[n]);
 }
  return 0;
}

strstr

char *strstr(const char *haystack, const char *needle);

strstr 是 C 语言标准库中的一个函数,用于在一个字符串中查找另一个字符串的第一次出现位置。如果找到匹配的子字符串,strstr 返回指向该子字符串在目标字符串中的首次出现位置的指针;如果没有找到,则返回 NULL。

haystack:指向要搜索的字符串(即主字符串)。
needle:指向要查找的子字符串。

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

int main() {
    const char *haystack = "Hello, World!";
    const char *needle1 = "World";
    const char *needle2 = "Python";

    // 查找 needle1 在 haystack 中的位置
    char *result1 = strstr(haystack, needle1);
    if (result1 != NULL) {
        printf("Found '%s' at position: %ld\n", needle1, result1 - haystack);
    } else {
        printf("'%s' not found in '%s'\n", needle1, haystack);
    }

    // 查找 needle2 在 haystack 中的位置
    char *result2 = strstr(haystack, needle2);
    if (result2 != NULL) {
        printf("Found '%s' at position: %ld\n", needle2, result2 - haystack);
    } else {
        printf("'%s' not found in '%s'\n", needle2, haystack);
    }

    return 0;
}

这样就可以了。我这里看着是很难,好像字符数很多一样,但是省去你这些不必要的字符,你会发现,本质上就一个if else 。

strtok

strtok 是 C 语言标准库中的一个函数,用于将字符串分割成一系列子字符串(标记)。它通过指定的分隔符来分割字符串,并在每次调用时返回下一个标记。strtok 是一个有状态的函数,因为它会记住上次调用的位置。

char *strtok(char *str, const char *delim);

str:是个字符串,定义了用作分隔符的字符集合。第一次调用时,这个参数应该是要分割的字符串;后续调用时,这个参数应该为 NULL。
delim:指向包含分隔符字符的字符串。这些字符用于确定分割点。

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

int main() {
    char str[] = "Hello, World! Welcome to C programming.";
    const char *delim = " ,.!";

    // 第一次调用 strtok
    char *token = strtok(str, delim);

    // 循环获取每个标记
    while (token != NULL) {
        printf("Token: %s\n", token);
        token = strtok(NULL, delim);  // 后续调用时,str 应该为 NULL
    }

    return 0;
}

那具体是怎么运行的呢?

第一个参数指定一个字符串,它包含了0个或者多个由delim字符串中一个或者多个分隔符分割的标记。strtok函数找到str中的下一个标记,并将其用 \0 结尾,返回一个指向这个标记的指针。

(注:strtok函数会改变被操作的字符串,所以在使用strtok函数切分的字符串一般都是临时拷贝的内容并且可修改。)

strtok函数的第一个参数不为 NULL ,函数将找到str中第一个标记,strtok函数将保存它在字符串中的位置。strtok函数的第一个参数为 NULL ,函数将在同一个字符串中被保存的位置开始,查找下一个标记。如果字符串中不存在更多的标记,则返回 NULL 指针。

/* strtok example */
#include <stdio.h>
#include <string.h>
int main ()
{
  char str[] ="- This, a sample string.";
  char * pch;
  printf ("Splitting string \"%s\" into tokens:\n",str);
  pch = strtok (str," ,.-");
  while (pch != NULL)
 {
    printf ("%s\n",pch);
    pch = strtok (NULL, " ,.-");
 }
  return 0;
}

这里放一个关于数组的运用的代码供大家参考。

#include <stdio.h>
int main()
{
   char *p = "[email protected]";
 const char* sep = ".@";
 char arr[30];
 char *str = NULL;
 strcpy(arr, p);//将数据拷贝一份,处理arr数组的内容
 for(str=strtok(arr, sep); str != NULL; str=strtok(NULL, sep))
 {
 printf("%s\n", str);
 }
}

感谢观看!

;