美文网首页
字符与字符串

字符与字符串

作者: 晓晓桑 | 来源:发表于2020-04-16 21:54 被阅读0次

字符输出

ascII码就是字符,字符就是码

int main(void) {
   //输出字符A
   printf("%c\n",'A');
   printf("%d\n",'A');//65 ascII码
   printf("%c",65);//A
   //输出字符的另一个方法
   putchar('\n');
   putchar('a');
   return 0;
}
int main(void) {
    char a = 'a';
    printf("%c\n", a);//a
    printf("%d\n", a);//97

    a = 65;
    printf("%c", a);//A
    return 0;
}

char占一个字节,256个数
表示范围:
有符号:-128~127(-27~27-1),
无符号:0~255(0~2^8)

int main(void) {
    char a = 'A';
    printf("%u,%u\n", sizeof a, sizeof(char));//1,1

    return 0;
}

字符的输入

scanf的含义

scanf的含义是:从缓冲区拿数据,我们输入空格的时候,内存是存的是空格,最后回车的时候会存回车\n。
所以下面两个scanf一次输入,跟一个scanf输入两个数效果一样。他不是调起平台,而是从平台拿数据。

int main(void) {
    //输入
    int d, c;
    scanf("%d", &d);
    scanf("%d", &c);//两个

    printf("%d,%d", d, c);//1,2
    return 0;
}
image.png
字符输入
int main(void) {
    //输入
    char c, d;
    scanf("%c", &c);
    scanf("%c", &d);
    printf("%c,%c", c, d);
    return 0;
}

当我输入一个字符,回车的时候,结果是:d成了一个换行。
分析:s是一个字符,然后换行\n也是一个字符,sancf从缓冲区拿数据所以打印d是\n。
输入字符的时候,输入前后都不要有空格回车什么的,要不然从缓冲区取数据的时候,会取出你不想要的东西。或者在输入字符前,把缓冲区清空。


image.png
清空缓冲区
  • 在输入字符之前setbuf(stdin, NULL);清除缓冲区
  • while((c=getchar())!='\n'&&c!=EOF);
int main(void) {
    //输入
    char c, d;
    scanf("%c", &c);
    setbuf(stdin, NULL);
    scanf("%c", &d);
    printf("%c,%c", c, d);
    return 0;
}
image.png
int main(void) {
    //输入
    char c, d;
    c = getchar();
    while ((c = getchar()) != '\n' && c != EOF);
    c = getchar();
    printf("%c,%c", c, d);
    return 0;
}

scanf_s

int main(void) {
    //输入
    char c, d;
    int a;
    char s[10];
    scanf_s("%c", &c);
    scanf_s("%c", &c, 1);//要写1
    scanf_s("%c%d", &c, 1, a);
    scanf_s("%s", s, 9); //要写9

    printf("%c,%c", c, d);
    return 0;
}

getchar()

一次读一个

int main(void) {
    //输入
    char c, d;
    int a;
    char s[10];

    c = getchar();

    printf("%c", c);
    return 0;
}

_getch()/getch()

随输入随读取,不需要回车确定吗,头文件conio.h
输入直接进缓冲区,控制台不显示。

大小写字母转换

数组字符与字符

字符'0': AscII码48

int main(void) {
    //大小写转化
    char c;
    while (1) {
        scanf("%c", &c);
        if (c >= 65 && c <= 90) {//大写字母
            printf("%c", c+32);
        } else if (c >= 97 && c <= 122) {
            printf("%c", c-32);
        } else if (c == '\n') {
            break;
        }
    }
    return 0;
}

字符数组

一维字符数组字符大小:1*数组长度 sizeof(char[5])

int main(void) {
    //字符数组
    //初始化部分数组元素,其他默认为0
    char arr[5] = {'a', 'b', 'c', 'd', 'e'};
    for (int i = 0; i < 5; ++i) {
        printf("%c",arr[i]);//abcde
    }
    printf("\n");
    char arr2[5] = {'a', 'b', 'c'};
    for (int i = 0; i < 5; ++i) {
        printf("%c",arr2[i]);//abc
        printf("%d,",arr2[i]);// 97,98,99,0,0,
    }

    return 0;
}

指针取数组元素
字符数组,要用for循环一个一个的字符输出,不能用printf("%s,", arr4)

int main(void) {
    //字符数组
    //初始化部分数组元素,其他默认为0
    char arr[5] = {'a', 'b', 'c', 'd', 'e'};
    char *p = &arr;
    //利用指针遍历数组
    for (int i = 0; i < 5; ++i) {
        printf("%c,", p[i]);//a,b,c,d,e,
        printf("%c,", *(p + i));//a,b,c,d,e, //*的优先级高于+,所以加括号
        printf("%c,", *p++);//a,b,c,d,e, //* 和++ 优先级一样,结合性:自右向左运算
    }
    return 0;
}

字符串

概念:以"\0"(0)结尾的字符数组
"\0"就是数字0,AscII码的第一个.如下:
char arr[5] = {'a', 'b', 'c', 'd', '\0'};
char arr1[5] = {'a', 'b', 'c', 'd', 0};
char arr2[5] = {'a', 'b', 'c'};
char arr3[5] = {'a', 'b', 'c', '\0'};
这就是字符串啦
原理:从给定的字符串地址开始,一个个的输出,遇到"\0"结束,没有"\0"停不下来,越界也不停止

int main(void) {
    //字符数组,要用for循环一个一个的字符输出,不能用printf("%s,", arr4)
    //字符数组
    char arr4[5] = {'a', 'b', 'c', 'd', '5'};
    //字符串
    char arr[5] = {'a', 'b', 'c', 'd', '\0'};
    char arr1[5] = {'a', 'b', 'c', 'd', 0};
    char arr2[5] = {'a', 'b', 'c'};
    char arr3[5] = {'a', 'b', 'c', '\0'};

    //原理:从给定的字符串地址开始,一个个的输出,遇到"\0"结束,没有"\0"停不下来,越界也不停止
    //所以字符数组,要用for循环一个一个的字符输出
    printf("%s,", arr);//abcd,

    char arr5[5] = {'a', 'b', 0, 'd', '5'};
    printf("%s,", arr5);//ab, //打印截止到0

    char arr6[5] = {'a', 'b', 'f', 'd', '\0'};
    printf("%s,", &arr[2]);//cd,, //从给定到首地址打印

    //字符串的专有输出,自带换行
    puts(arr);//abcd
    puts(&arr[2]);//cd //
    return 0;
}

应用将字符串abcd 以字符abcd打印出来

void outString(char *str1);
int main(void) {
    char arr4[5] = {'a', 'b', 'c', 'd', '\0'};
    outString(arr4);
    return 0;
}

//遍历字符串
void outString(char *str1) {
    for (str1; *str1 != '\0'; str1++) {
        // 下面两种都行
        putchar(*str1);//abcd
        printf("%c",*str1);//abcd
    }
}

字符串的声明方式

  • 有元素个数
    char arr[5] = {'a', 'b', 'c', 'd', '\0'};
    char arr1[5] = {'a', 'b', 'c', 'd', 0};
    char arr2[5] = {'a', 'b', 'c'};
    char arr3[5] = {'a', 'b', 'c', '\0'};

//注意
char str[5]; //声明之后,只能一个一个的赋值或者循环去赋值
str[0]='a';
str[1]='b';
str[2]='c';
str[3]='d';
str[4]='\0';

  • 无元素个数
    不指定元素个数,就一定要进行初始化,一定要手写"\0"
    char arr[]={'a','b','c','\0'}

常量字符串"hello"

  • 常量字符串不能被修改
int main(void) {
    char *p = "hello xiao";
    //可以修改指针的指向,
    p="w222";
    printf("%s", p);//w222
    printf(p);//w222 打印字符串另一个方法 // printf("hello xiao")
    
    //!!但是 下面修改值不能被修改,下面是错误的❌
    *p="wqqq";//❌
    *p='weee';//❌
    return 0;
}
  • 常量字符串自带'\0'
  • char *p = "hello xiao";
    printf("%s", p);
int main(void) {
    printf("%s", "hello");//hellohello

    char *p = "hello xiao";
    printf("%s", p);//xiao
    return 0;
}

用常量字符串初始化数组

int main(void) {
    //初始化数组,这两种写法只能在初始化的时候用,赋值看下面
    //方法一
    char str[20] = "hellp xiao"; //元素个数要大于等于字符串的长度
    printf("%s\n", str);//hellp xiao

    //方法二
    char str2[] = "hellp xiao";//不写长度,系统计算长度,然后在栈区申请空间

    str2 = "qwe";//❌
    str[10] = "qwe";❌
    return 0;
}

char str[20] = "hello xiao"; 解读

  • 常量字符串是自带/0的,所以,"hello xiao"的长度是11(空格也别落下)
  • 如下图,常量字符串初始化数组时,常量"hello xiao"存在常量区,而str存在栈区,当"hello xiao"赋值给str后,会依次把值赋值到栈区。所以当我们操作str的时候(比如str[0]='w'),是操作的栈区的内存,是可以修改的。但是在字符串常量中:char *p = "hello xiao"; 因为p直接指向的是"hello xiao"常量,所以,是不能修改他的值的*p="wqqq";❌


    image.png

字符数组的赋值

int main(void) {

    char str[20] = "hello";
    printf("%s\n", str);//hello
    //方法一 用字符常量
    char *p = "www";

    int i = 0;
    for (; *p != '\0'; ++p) {
        str[i] = *p;
        i++;
    }
    printf("%s\n", str);//wwwlo,
    // 分析原因:因为在i='\0'的时候没有赋值给str,把'\0'赋值给他最后一项就好了
    //加完 '\0'之后 str="www\0o"
    str[i] = '\0';
    printf("%s\n", str);//www


    //方法二
    //用数组的话
    char str1[4] = "www";
    //遍历数组str1
    //剩下的跟上面一样

    return 0;
}

字符串操作函数

strcpy:复制函数

int main(void) {
    char str[20] = "hello";
    char str1[] = "xiao";
    char *p = str1;
    //复制函数,第一个函数一定要是栈区内存的
    strcpy(str, str1);// 可以写成strcpy(str, p);
    printf("%s", str);//xiao
    return 0;
}

strncpy() 复制几个字符

int main(void) {
    char arr[] = "abcde";
    strncpy(arr, "hhh", 3);
    printf("%s", arr);//hhhde
}

字符串的输入

scanf("%s\n", str); 不能空格

  • 不能读空格,注意%c会把空格读出来,而%s会把空格当作凤娥
int main(void) {
    char str[20];
    scanf("%s\n", str);
    printf("%s", str);
}
image.png

缓冲区的数据会一个一个读,所以下面这个例子,当输入qwe qq,scanf %s看到空格就不取数据了(遇到空格scanf会把'\0'加到str里面去,所以str后缀就不是乱码了)。但是qq还在缓冲区里,所以下一次输入的时候,scanf取之会把qq取出来,aa在缓冲区

int main(void) {
    char str[20];
    scanf("%s\n", str);
    printf("%s", str);
    scanf("%s\n", str);
    printf("%s", str);
}
image.png

gets 可以读空格

int main(void) {
    char str[20];
    gets(str);
    printf("%s", str);
}
image.png

中午与字符 一个汉子占两个字节

一个char能表示(0255/-128127)256个数,这256个数被AscII码占有了,所以中文等其他数字就要用>255的数字表示,即大于1的字节。
一个汉子占两个字节,用一个char肯定装不了,要用两个cahr,也就是字符数组,然后末尾加个"\0",他就变成字符串了。
char str[3]="晓",输printf("%s",str); 或者printf("%c%c",str[0],str[1])//%c一定要挨在一起。

int main(void) {
    char str[3] = "晓"; //双引号
    printf("%s\n", str);//晓
    printf("%c%c\n",str[0],str[1]);//%c%c
    return 0;
}
如何打印汉子数字码
  1. 汉子国标码查询
  2. printf("%x%x\n",str[0],str[1]); %x%x
  3. 对应的十进制的打印:
int main(void) {
    char str[3] = "晓"; //双引号
    printf("%s\n", str);//晓
    //方法一
    //打印
    printf("%x%x\n", str[0], str[1]);//%c%c  这是国际码ffffffe6ffffff99

    //方法二
    printf("%x\n", *(short *) str);//ffff99e6 正常顺序是 e699,
    // 但是直接转成short之后,因为内存从高地址到低地址读,所以成了99e6
    //所以得让str[0]和str[1]交换
    char temp;
    temp = str[0];
    str[0] = str[1];
    str[1] = temp;
    printf("%x", *(short *) str);//ffffe699,这个就是编码了

    //❗️注意:这个是无符号的
    unsigned short a = *(short *) str;
    return 0;
}

字符串其他的操作函数

strlen 求字符数
size_t len = strlen(const char *__s):求字符数
int main(void) {
    char *p = "12345"; //双引号
    char str[] = "12345";

    //size_t 就是unsigned int,他只不过是个类型重命名
    size_t len = strlen(p);//size_t len = strlen(str);
    printf("%d\n", len);//5 strlen求对是字符数,不算'\0'

    return 0;
}

int strcmp(const char *string1,const char *string2)

//比较两个字符串第一个不同的字符
//string1大:返回值>0,
//string2大:返回值<0,
//相等,返回值=0
int strcmp(const char *string1,const char *string2)

int main(void) {

    int a = strcmp("abcd", "abceaaa");
    printf("%d",a);//-1
    return 0;
}
int strncmp(const char *string1,const char *string2,size_t count)

比较前count个字符

strcat 字符串末尾拼接
int main(void) {
    char str[20] = "abc";
    strcat(str, "abce");
    printf("%s", str);//abcabce
    return 0;
}
strncat 把第n个参数的前2个字符拼接到第一个参数末尾
int main(void) {

    char str[20] = "abc";
  //把第二个参数的前2个字符拼接到str上
    strncat(str, "abce",2);
    printf("%s", str);//abcab

    return 0;
}
atoi 字符串转化成数组,相当于java中的integer.parseint
int main(void) {

    int a = atoi("1");
    int b = atoi("3333");
    printf("%d,%d", a,b);//1,3333

    return 0;
}
itoa
int main(void) {

    char str[20]={0};
    //第三个参数是几进制的意思
    itoa(235,str,2);
    printf("%s", str);//先转化成2进制的数,然后再转化成字符串

    return 0;
}
sprintf
int main(void) {

    char str[20] = {0};
    //把第二个参数以字符串的形式"12,v,12.300000"赋值给第一个参数str
    sprintf(str, "%d,%c,%f", 12, 'v', 12.3f);
    printf(str);//12,v,12.300000
    return 0;
}

转义字符和转换字符

转义字符:\
转换字符:%


image.png image.png
image.png
  • \字母:占一个字节
int main(void) {
    printf("%u\n",strlen("\n"));//1//转义字符换行
    printf("%u\n",strlen("\w"));//1//不是转义字符
    return 0;
}
  • \数字 :代表一个字节
    分为:
    \+数字 : \123
    8进制。数字位数限制:1~3位。数字值限制:0~255(8进制是0~377)
    \+0+数字:
    8进制。数字位数限制:1~2位。数字值限制:0~63(8进制是0~77)
    \+x+数字:
    16进制。数字位数限制:1~2位。数字值限制:0~255(16进制是0~ff)
    在上面的范围内,是一个字节,超过上面的范围就不一定咯。
    测试:
int main(void) {

    //分析:因为\+数字是8进制的,8进制最高位数字是7
    //系统会把\58 看成是\5和8,所以是2
    printf("%u\n", strlen("\57"));//1
    printf("%u\n", strlen("\58"));//2

    //因为\+数字 超过了377,所以他从末尾减一位,分成\37和8
    //注意:如果超过的很大,直接报错,比如\400
    printf("%u\n", strlen("\378"));//2

    //分析:因为\0+数字是8进制的,8进制最高位数字是7
    printf("%u\n", strlen("\018"));//2

    //xff一个字符,w是一个字符,因为w不是16进制的,所以不报错
    printf("%u\n", strlen("\xffw"));//2

    //报错,超过两个了
    printf("%u\n", strlen("\xfff"));//2
    return 0;
}

字符串数组与二维字符数组

  • 字符串数组
    每一个元素都是这个字符串的首地址。
int main(void) {

    //字符串数组
    //每个元素都装着字符串的首地址,每个元素都是char *,
    //即:每个元素都是指向字符串首地址的指针。
    char *str[3] = {"abd", "asdss", "wlekdc"};

    //读取:
    for (int i = 0; i < 3; ++i) {
        printf("%s,", str[i]);//abd,asdss,wlekdc,
    }
    printf("\n");

    //修改:
    //str[0]可以指向新的字符串
    str[0] = "123";
    printf(str[0]);//123
    printf("\n");

    //读字符串常量中的某一个字符
    printf("%c", *str[1]);//"asdss"中的a
    
    //注意因为是字符串常量,所以无法修改他的值。
    *str[1]='w';//这个是错的❌.常量无法修改

    return 0;
}
  • 二维字符数组
lude <stdio.h>
#include <string.h>
#include <stdlib.h>

int main(void) {

    //可以用字符串初始化,也可以用字符初始化
    //tr[2][4] 2个元素,,每个元素4个字节数
    char str[2][4] = {"adc", "12"};//因为字符串默认有一个'\0',所以最多就是三个字节数/

    //读取字符串
    for (int i = 0; i < 2; ++i) {
        printf("%s ", str[i]);//adc 12
    }

    //读取字符
    for (int i = 0; i < 2; ++i) {
        for (int j = 0; j < 4; ++j) {
            if (str[i][j] != '\0') {
                printf("%c ", str[i][j]);//a d c 1 2
            }

        }
    }

    //注意:
    //这个是常量区的adc 12赋值到栈区的str中了,所以str操作的是栈区的空间
    //这个类似与 char str2[4]="abc" //把常量区里面的abc赋值到栈区的str2中
    //所以,跟char *str[3]={"acd","ss","qwxa"}不同的是,他可以修改元素任意的字符,修改的是栈区的内容
    str[0][0] = 'n';
    printf("%s",str[0]);//ndc

    return 0;
}

相关文章

  • 2018-10-25

    字符串与数字: 数字与数字 字符串与boolean(真假类型) 字符串与字符串 数字与boolean(真假类型)

  • (三)C语言之字符串与字符串函数

    (三)C语言之字符串与字符串函数 字符串与字符串函数 1. 字符串 使用字符数组存储字符串,\0 表示结束符,字符...

  • iOS中的NSString与NSMutableString

    字符串的创建 字符串读写 字符串的比较 字符串的搜索 字符串截取 字符串替换 字符串与路径 字符串转换 NSMut...

  • 5.bytes和bytearray

    目录1.字符串与字节2.bytes3.bytearray 1.字符串与字节 1.1 字符串与bytes 字符串是字...

  • Python数据结构之字符串

    数据结构之字符串类型 本节知识体系 字符串语法 输入和输出 注释与长字符串 原始字符串 转义与转义字符 字符串的格...

  • 11.字符串:

    字符串替换: 字符串拼接和包含: 字符串分割: 字符串剪切: 字符串的大小写转换: 等号与字符串equals用法:

  • JavaScript的内置函数

    escape() 与 unescape() :对字符串进行 编码与解码 eval(字符串):用于执行字符串所代表的...

  • Swift string to array array to

    数组与字符串转换 Swift 字符串转数组: Swift 数组转字符串:

  • NSString

    1、字符串截取 2、字符串操作 3、字符串搜索 4、字符串的比较 5、字符串的读写 6、字符串与路径 参考文章iO...

  • Swift基础 - 字符串

    简单拼接 字符串遍历 字符串长度 格式化字符串 Swift字符串与OC中字符串对比 Swift中是String类型...

网友评论

      本文标题:字符与字符串

      本文链接:https://www.haomeiwen.com/subject/iuxaphtx.html