C语言——字符串函数的补充

简介: 还是字符串函数的知识



前面我们学习了4个函数——strlen\strcpy\strcat\strcmp,这些函数的长度都是不受限制的,今天,我们自然是要介绍一些其他的函数。内容可能相对来说比较多。

文章目录

长度受限制的字符串函数

strncpy

char * strncpy ( char * destination, const char * source, size_t num );
  1. Copies the first num characters of source to destination. If the end of the source C string (which is signaled by a null-character) is found before num characters have been copied, destination is padded with zeros until a total of num characters have been written to it.
  2. 拷贝num个字符从源字符串到目标空间。
  3. 如果源字符串的长度小于num,则拷贝完源字符串之后,在目标的后边追加0,直到num个。

下面,我们来简单测试一下:

#include <stdio.h>
#include <string.h>
int main()
{
  char arr1[20] = "abcdef";
  char arr2[] = "hello world";
  strncpy(arr1, arr2, 5);
  printf("%s\n", arr1);
  return 0;
}

运行:

我们来看看上面的第3点

#include <stdio.h>
#include <string.h>
int main()
{
  char arr1[20] = "abcdef";
  char arr2[] = "ghi";
  strncpy(arr1, arr2, 5);//arr2只有3个这里却要拷贝5个,这是怎么一回事呢
  printf("%s\n", arr1);
  return 0;
}

F10调试看看还没拷贝前arr1和arr2是这样子的:

拷贝完成之后呢?

我们可以清楚的看到,内容不够时会用’\0’来补充!

strncat

char * strncat ( char * destination, const char * source, size_t num );
  1. Appends the first num characters of source to destination, plus a terminating null-character.
  2. If the length of the C string in source is less than num, only the content up to the terminating null-character is copied.
#include <stdio.h>
#include <string.h>
int main()
{
  char arr1[20] = "hello\0xxxxx";
  printf("%s\n", arr1);
  char arr2[] = "world";
  strncat(arr1, arr2, 3);
  printf("%s\n", arr1);
  return 0;
}

结果我们都是知道的,那过程是什么样子的呢?我们不妨调试来看一看:追加之前:

追加后:

我们可以清楚的看到,会在最后面自动加上一个’\0’

那如果追加的长度大于本身呢?会不会像strncpy一样却多少就补多少个’\0’呢?测试一段代码:

#include <stdio.h>
#include <string.h>
int main()
{
  char arr1[20] = "hello\0xxxxx";
  printf("%s\n", arr1);
  char arr2[] = "abc";
  strncat(arr1, arr2, 6);
  printf("%s\n", arr1);
  return 0;
}

追加前:

追加后:

答案是并没有,只会添加一个’\0’。通过简单的分析,我们也大概知道了strncat的原理。

strncmp

int strncmp ( const char * str1, const char * str2, size_t num );

比较到出现另个字符不一样或者一个字符串结束或者num个字符全部比较完。

#include <stdio.h>
#include <string.h>
int main()
{
  char arr1[] = "abcdef";
  char arr2[] = "abc";
  int ret = strncmp(arr1, arr2, 4);
  printf("%d\n", ret);
  if (ret == 0)
  {
    printf("==\n");
  }
  else if (ret < 0)
  {
    printf("<\n");
  }
  else
  {
    printf(">\n");
  }
  return 0;
}

实际上,这些函数多了个n也就多了长度限制,并没有多大的区别,长度受限的字符串函数使得代码更加严谨一些,我们尽可能去使用。

字符串查找

strstr

char * strstr ( const char *str1, const char * str2);

Returns a pointer to the first occurrence of str2 in str1, or a null pointer if str2 is not part of str1.

简单理解,这个函数就是查找子串的函数

#include <stdio.h>
#include <string.h>
int main()
{
  char email[] = "huangweichang@qq.com";
  char substr[] = "eichang";
  char*ret = strstr(email, substr);
  if (ret == NULL)
  {
    printf("子串不存在\n");
  }
  else
  {
    printf("%s\n", ret);
  }
  return 0;
}

关于怎么使用并不是重点,重点是我们怎么去进行模拟实现!

strstr的模拟实现

我们先来说一说查找的过程:

可以分为两种情况来说明:

一种是简单的情况:一次匹配就能找到

另一种是比较复杂的情况:第一次匹配没有找到,需要记录当前的位置,继续匹配下去,需要找多次才能找到

下面进行简单的模拟实现:

#include <assert.h>
#include <stdio.h>
char*my_strstr(const char*str1,const char*str2)
{
  assert(str1 && str2);
  const char* s1 = str1;
  const char* s2 = str2;
  const char* p = str1;
  while (*p)
  {
    s1 = p;
    s2 = str2;
    while (*s1!='\0'&&*s2!='\0'&&* s1 == *s2)
    {
      s1++;
      s2++;
    }
    if (*s2 == '\0')
    {
      return (char*)p;
    }
    p++;
  }
  return NULL;
}
int main()
{
  char email[] = "huangweichang@qq.com";
  char substr[] = "eichang";
  //char*ret = strstr(email, substr);
  char* ret = my_strstr(email, substr);
  if (ret == NULL)
  {
    printf("子串不存在\n");
  }
  else
  {
    printf("%s\n", ret);
  }
  return 0;
}

找子串这里可以用KMP算法来进行实现,不过较为复杂,就不展开说明了。

strtok

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

sep参数是个字符串,定义了用作分隔符的字符集合

第一个参数指定一个字符串,它包含了0个或者多个由sep字符串中一个或者多个分隔符分割的标 记。

strtok函数找到str中的下一个标记,并将其用 \0 结尾,返回一个指向这个标记的指针。(注: strtok函数会改变被操作的字符串,所以在使用strtok函数切分的字符串一般都是临时拷贝的内容 并且可修改。)

strtok函数的第一个参数不为 NULL ,函数将找到str中第一个标记,strtok函数将保存它在字符串 中的位置。

strtok函数的第一个参数为 NULL ,函数将在同一个字符串中被保存的位置开始,查找下一个标 记。

如果字符串中不存在更多的标记,则返回 NULL 指针.

我觉得这是一个比较奇怪的函数,不过并不妨碍我们认识它切割字符串

#include <stdio.h>
#include <string.h>
int main()
{
  const char* sep = "@.";
  char email[] = "huangweichang@qq.com";
  char cp[30] = { 0 };
  strcpy(cp, email);
  char*ret = strtok(cp, sep);
  printf("%s\n", ret);
  ret = strtok(NULL, sep);
  printf("%s\n", ret);
  ret = strtok(NULL, sep);
  printf("%s\n", ret);
  return 0;
}

怎么和for循环联系起来❓

#include <stdio.h>
#include <string.h>
int main()
{
  const char* sep = "@.";
  char email[] = "huangweichang@qq.com";
  char cp[30] = { 0 };
  strcpy(cp, email);
  char* ret = NULL;
  for (ret = strtok(cp, sep); ret != NULL; ret = strtok(NULL, sep))
  {
    printf("%s\n", ret);
  }
  return 0;
}

错误信息报告

strerror

char * strerror ( int errnum );

返回错误码,所对应的错误信息。

#include <stdio.h>
#include <string.h>
int main()
{
  printf("%s\n", strerror(0));
  printf("%s\n", strerror(1));
  printf("%s\n", strerror(2));
  printf("%s\n", strerror(3));
  printf("%s\n", strerror(4));
  printf("%s\n", strerror(5));
}

这些并不需要我们记住,error-C语言设置的一个全局的错误码存放的变量

举个例子:

#include <stdio.h>
#include <string.h>
int main()
{
    FILE* pf = fopen("test.txt", "r");
  if (pf == NULL)
  {
    printf("%s\n", strerror(errno));
    return 1;
  }
  else
  {
  }
    return 0;
}

字符分类函数

这些函数是比较多的,零零散散,并不 一一举例子说明了,在这里,大家可以认识认识并自己动手实践一下:

函数 如果他的参数符合下列条件就返回真

iscntrl 任何控制字符

isspace 空白字符:空格‘ ’,换页‘\f’,换行’\n’,回车‘\r’,制表符’\t’或者垂直制表符’\v’

isdigit 十进制数字 0~9 isxdigit 十六进制数字,包括所有十进制数字,小写字母af,大写字母AF

islower 小写字母a~z

isupper 大写字母A~Z

isalpha 字母az或AZ

isalnum 字母或者数字,az,AZ,0~9

ispunct 标点符号,任何不属于数字或者字母的图形字符(可打印)

isgraph 任何图形字符

isprint 任何可打字符,包括图形字符和空白字符

#include <stdio.h>
#include <ctype.h>
int main()
{
    int i = 0;
    char str[] = "Test String.\n";
    char c;
    while (str[i])
    {
        c = str[i];
        if (isupper(c))
            c = tolower(c);
        putchar(c);
        i++;
    }
    return 0;
}




相关文章
|
1月前
|
C语言 C++
【C语言】解决不同场景字符串问题:巧妙运用字符串函数
【C语言】解决不同场景字符串问题:巧妙运用字符串函数
|
27天前
|
存储 C语言
【c语言】字符串函数和内存函数
本文介绍了C语言中常用的字符串函数和内存函数,包括`strlen`、`strcpy`、`strcat`、`strcmp`、`strstr`、`strncpy`、`strncat`、`strncmp`、`strtok`、`memcpy`、`memmove`和`memset`等函数的使用方法及模拟实现。文章详细讲解了每个函数的功能、参数、返回值,并提供了具体的代码示例,帮助读者更好地理解和掌握这些函数的应用。
22 0
|
1月前
|
存储 安全 编译器
深入C语言库:字符与字符串函数模拟实现
深入C语言库:字符与字符串函数模拟实现
|
1月前
|
C语言
C语言常见字符函数和字符串函数精讲
C语言常见字符函数和字符串函数精讲
|
1月前
|
C语言
【C语言】模拟实现深入了解:字符串函数
【C语言】模拟实现深入了解:字符串函数
|
3月前
|
安全 程序员 C语言
【C语言】字符串函数及其模拟实现
【C语言】字符串函数及其模拟实现
|
3月前
|
C语言
【C语言篇】字符和字符串以及内存函数详细介绍与模拟实现(下篇)
perror函数打印完参数部分的字符串后,再打印⼀个冒号和⼀个空格,再打印错误信息。
63 0
|
3月前
|
存储 安全 编译器
【C语言篇】字符和字符串以及内存函数的详细介绍与模拟实现(上篇)
当然可以用scanf和printf输入输出,这里在之前【C语言篇】scanf和printf万字超详细介绍(基本加拓展用法)已经讲过了,这里就不再赘述,主要介绍只针对字符的函数.
55 0
|
4月前
|
存储 缓存 C语言
【C语言】字符函数,字符串函数,内存函数
C语言中的字符串函数和内存函数
57 0
【C语言】字符函数,字符串函数,内存函数
|
5月前
|
C语言
【c语言】字符串函数的模拟实现(二)
【c语言】字符串函数的模拟实现(二)
26 1