avatar

zian

A text-focused Halo theme

  • Java
  • 面试
  • 首页
  • C语音
  • liunx
  • 数据结构与算法
  • 控制台
Home C语言 字符串
文章

C语言 字符串

Posted 2024-12-27 Updated 2025-01- 3
By Administrator
14~18 min read

声明方式:

// 1. 类型一:字节数组定义字符串
char str[4] = "abc"; // 手动指定长度
char str2[] = "1234"; // 根据内容自动定义长度

//2.类型二:通过指针声明
char* zStr1 = "1234";

字节数组声明字符串细节

NaN. 存储的字节数组。
NaN. 在底层,存储的时候,C语言还是帮我们转换成字节数组进行保存,并且在末尾加上 \0 做结束符号:char str[2] = "a" 其实是 {'a' , '\0'}
NaN. 数组的长度要么不写,如果写的需要预留结束符号的位置
NaN. 字节数组 + 双引号定义字符串,字符串内容是可以改变的 【可读、可写的】

指针声明声明字符串细节

NaN. 变量中存储的内存地址值
NaN. 在底层,存储的时候,C语言还是帮我们转换成字节数组进行保存,并且在末尾加上 \0 做结束符号:char str[2] = "a" 其实是 {'a' , '\0'}
NaN. 指针声明的支付串,会将字符数组放入只读常量区中。
NaN. 只读常量区的特点:

  • 只读常量区中的数据是不可以修改的
  • 只读常量区定义好的数据是可以复用的,如果需要声明一个只读常量区的数据,创建内存空间之前,会检测常量区是是否存在该数据了,如果存在了就直接返回该数据对应的地址值,如果没有才会创建内存空间。
  • 修改就会出现段错误:``Segmentation fault (core dumped)``

变量字符串

#include <stdio.h>

int main() {

    char str[100] = "";
    printf("输入字符串:");
    scanf("%s", str); // 引用数据类型变量中存储的就是指针,所以在 scanf 的参数就无需在变量前面加上 & 符号

    printf("%s \n", str);
    //for (int i = 0; i < 100; i++)
    //{
    //  if (str[i] == '\0') {
    //      break;
    //  }
    //  printf("%c \n", str[i]);
    //}

    char* c = str;
    while (1) {
        char t = *c;
        if (t == '\0') {
            break;
        }
        printf("%c \n", t);
        c++;
    }

    return 0;

}

字符串常用方法

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


int main() {
    // string 方法

    char* str1 = "abc";

    char str2[100] = "Abc";

    char str3[5] = { 'q','w','e','r','\0' };


    printf("---------获取字符串长度 strlen --------\n");
    //printf("str1=%zd \n", strlen(str1));
    //printf("str2=%zd \n", strlen(str2));
    //printf("str3=%zd \n", strlen(str3));
    // 细节:获取长度 = 看的字符长度 - 1 【不包括结束标记符 \0 】 ;

    printf("---------字符串拼接 strcat --------\n");
    /*strcat(str2, str3);
    printf("%s \n", str2);
    printf("%s \n", str3);*/
    // 结果:将后一个参数的字符内容拼接到前一个字符中
    // 细节:
    //  1. 前一个参数的字符要是可写的字符串才行
    //  2. 前一个参数要有足够空间可以容纳后一个字符串的全部内容才能拼接成功 需要的空间 >= 原来的空间 + 拼接的空间



    printf("---------字符串拷贝 strcpy --------\n");
    /*strcpy(str2, str3);
    printf("%s \n", str2);
    printf("%s \n", str3);*/

    // 结果:将后一个参数的所有内容拷贝的前一个参数中,这里的拷贝是覆盖原来的内容
    // 细节:
    //  1. 前一个参数的字符要是 可写的字符串才行
    //  2. 前一个参数要有足够空间可以容纳后一个字符串的全部内容才能拷贝成功 需要的空间 >= 拷贝的空间


    printf("---------比较字符串 strcmp --------\n");
    //int res = strcmp(str1, str3); 
    //printf("%d \n", res);
    // 结果:得到一个 0 或者非零的结果: 如果是 0 就代表两个字符串一模一样 【内容和字符位置都是一样的】


    printf("--------- 字符串转小写  strlwr --------\n");
    //_strlwr(str2);
    //printf("%s \n", str2);
    // 细节:strlwr 转换的字符串必须是可写的 , 只能转换英文字符

    printf("--------- 字符串转大写  strupr  --------\n");
    _strupr(str2);
    printf("%s \n", str2);


    return 0;
}

image-jvyk.png

拓展

清理输入缓冲区

在循环使用 scanf 函数接收的输入的数据,当输入的错误的,并且在循环中输出了其他内容,会导致死循环。

解决方法: 利用 while + getchar 将所有错误数据接收起来,但是不做任何处理,就是实现了,清除所有错误输入的效果。

     // 清除输入缓冲区中的错误输入 , 清理所有的错误输入 ,
      while ( getchar() != '\n' ) {
        ;
      }

自定义字符串拼接

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

void forArr(char* arr, int len) {
  for ( int i = 0; i < len; i++ ) {
    printf("%c ", arr[i]);
  }
  printf("\n");
}

/// @brief  字符串拼接
/// @param str1 
/// @param str2 
/// @return 字符串
/**
strlen + 指针
*/
void strJoin(char* str1, char* str2, char* str3) {
  int len1 = strlen(str1); // 6
  int len2 = strlen(str2); // 6
  int len3 = len1 + len2;
  // TODO bug 无法接受 str2 的值
  for ( int i = 0; i < len3; i++ ) {  // 0 -  6
    *(str3)++ = i < len1 ? *(str1++) : *(str2++);
  }
}

/**
利用指针
*/
void  strJoin2(char* str1, char* str2, char* str3) {
  while ( *str1 != '\0' ) {
    *str3 = *str1;
    str3++;
    str1++;
  }

  while ( *str2 != '\0' ) {
    *str3 = *str2;
    str3++;
    str2++;
  }
}


int main(int argc, const char* argv[]) {
  char* str1 = "123456";
  char* str2 = "abcdef";
  char* str3;
  // strJoin(str1, str2, str3);
  strJoin2(str1, str2, str3);

  printf("%s\n", str3);
  return 0;
}

注意点:

  1. 不要考虑使用函数返回的数据,因为这里需要返回指针,如果直接返回指针,指针会随着函数的执行完毕后消失。
  2. 指针++ ,去到一个存储数据的位置。

编写一个程序,清除用户输入字符串中的空格符并将之输出。(例如用户输入”a b”,输出”ab”)

#include <stdio.h>
#include <ctype.h>

int main(int argc, const char* argv[]) {
  int count = 0;
  char str[100];
  char* ptr = str; // 初始化指针,要不然容易出问题

  char c;
  while ( (c = getchar()) != '\n' ) {
    if ( !isspace(c) ) {
      *(ptr++) = c;
      count++;
    }
  }
  // 添加字符串的结束标记 ,不然会出现乱码;
  str[count] = '\0';
  printf("%s \n", str);

  return 0;
}

注意:

  1. 指针记得要初始化,要不然容易出错
  2. 如果是将一些字符存入字符数据中,记得在最后添加一个结束标识 `\0`;
C语音
License:  CC BY 4.0
Share

Further Reading

Jan 7, 2025

C语言 其他

作用域 关键字 register 在C语言中,register 关键字是一种存储类说明符,用于建议编译器将变量存储在CPU寄存器中,而不是内存中。这样做可以提高访问变量的速度,因为寄存器的访问速度通常比内存快得多。然而,这个关键字只是一个提示,编译器可以选择忽略它。 使用register关键字的变量

Jan 6, 2025

C语言 结构体

结构体 问题的引入 多个相同数据类型的数据可以用数组表示,那么,如果多个不同数据类型的数据如何用一个集合表示呢?? 前面我们所介绍的普通数据类型实际上远远未能满足我们对实际应用中的要求,比如说一个学生,可能包含的属性有年龄、姓名、分数等等,不可能用一个基本数据类型(int 、float 、char)

Dec 28, 2024

C语言 内存

内存 什么是内存 软件在运行是,临时用来存储数据的 操作系统会将内存按照字节划分为 N 多个小格子 什么是内存地址 其实就是格子的编号 32 位操作系统:以 32 位的二进制表示 64 位操作系统:以 64 位的二进制表示 内存地址的作用 快速操作内存中存储的数据 C 语言中如何获取内存地址 &变量

OLDER

嵌入式

NEWER

C语言 指针

Recently Updated

  • 其他
  • Elasticsearch 面试
  • Spring 面试
  • RabbitMQ 面试
  • Redis 面试

Trending Tags

ruoyi docker java

Contents

©2025 zian. Some rights reserved.

Using the Halo theme Chirpy