第三周总结02

一、字符串


字符:人能看的懂的符号或图案,在内存中以整数形式存储,根据ASCII码表中的对应关系显示出相应的符号或图案

串:是一种数据结构,存储类型相同的若干个数据

对于串行结构的处理是批量性的,会从头开始直到遇到结束标志停止(~0)

字符串:由字符组成的串行结构,结束标志是 '\0'

二、字符串的存在形式


字符数组:

由char组成的数组,注意要为'\0'预留位置,初始化麻烦

用的是栈内存,数据可以修改

char str[10] = {'a','b','c',...};
printf("%s\n",str);
字符串字面值:

"由双引号包含的若干个字符"

末尾会隐藏一个'\0',定义也方便

字符串字面值就是以地址形式存在的,是常量,存储在代码段中,不能修改,否则会发生段错误

注意:相同内容的多份字符串字面值,在代码段中只会存在一份

sizeof("xxxx") 计算出 字符个数+1

常用方式:

字符数组[ ] = "字符串字面值";

会自动为 '\0' 预留位置

注意:赋值完成后,该字符串在内存中有两份,一份在代码段,另一份在栈内存中(可修改)

三、字符串的输入和输出


输入:
// scanf("%s",地址);
// 缺点:不能输入空格
char str[100] = {};
scanf("%s",str);
printf("%s\n",str);
// char *gets(char *s);
// 返回值:s 链式调用
// 功能:输入字符串到s中,能够输入空格
// 缺点:有警告,输入的长度不受限制,有危险

char str[100] = {};
// gets(str);
printf("%s\n",gets(str));
// char *fgets(char *s,int size,FILE *stream);
// 功能:输入长度最多为 size-1 的字符串,会自动为'\0'预留位置
//      超出部分不接收,不足时最后的'\n'(回车)也会一起接受

char str[100] = {};
// fgets(str,10,stdin);
printf("%s\n",fgets(str,10,stdin));
输出:
// printf("%s",地址)
int puts(const char *s);
// 功能:输出一个字符串,并且会自动在末尾打印一个'\n'
// 返回值:成功输出的字符个数

四、输出缓冲区


缓冲区机制可以提高数据的读写速度,还可以让低速的设备与高速的CPU之间协调工作

程序要显示的数据并不会立即显示到屏幕上,而是先存储到输出缓冲区中,当满足一定条件时才会从输出缓冲区显示到屏幕上

1、遇到 '\n'

2、遇到输入语句

3、当缓冲区满了 4K

4、程序正常结束时

5、fflush(stdout); 手动刷新输出缓冲区

五、输入缓冲区


程序中输入的数据并不会立即从键盘接收到变量中,而是当按下回车后,先存储到输入缓冲区中,然后再从缓冲区中读取到变量内存中

情况1:需要输入的是整型\浮点型时,而缓冲区中的数据是字符型或符号时,此时读取会失败,并且该数据会继续残留在输入缓冲区中,会继续影响剩下的输入

解决:根据scanf的返回值判断输入是否有问题,如果读取失败,则先清理输入缓冲区后重新输入直到读取成功为止

while(3 != scanf("%d%d%d",&a,&b,&c))
{
    stdin->_IO_read_ptr = stdin->_IO_read_end;
    // 把输入缓冲区的位置指针从当前位置,移动到末尾相当于清理输入缓冲区
    // 注意:只能在Linux系统下使用
}

情况2:通过 fgets 可以指定读取 size-1个 字符,但是如果输入超过 size-1 个,字符会残留在输入缓冲区中,继续影响接下来的输入

解决:判断字符串的最后一个字符是否是'\n',如果不是,说明缓冲区中有残留

// 方法1
int len = 0;
while(str[len]) len++;// len是'\0'的下标
if('\n' != str[len-1])// '\0'前面不是'\n'则清理
{
    scanf("%*[^\n]");
    // 从缓冲区中读取任意类型数据并丢弃,直到遇到'\n'停止
    scanf("%*c");
    // 从缓冲区中读取任意字符类型数据并丢弃,清理'\n'
}

情况3:当先输入整型或浮点型,再输入字符形式,输入完整型或浮点型后按下的回车或空格,会残留在输入缓冲区,刚好被后面的字符型接收,影响输入

解决:在%c或者gets()前面加空格

scanf(" %c");

六、字符串相关函数


#include <string.h>
size_t strlen(const char *s);
// 功能:计算字符串的长度,不包括'\0'
// 返回值:返回字符个数

char str[100] = "hello";
printf("strlen=%d\n",strlen(str));// 字符个数
printf("size=%d\n",sizeof("hello"));// 字节数
#include <string.h>
char *strcpy(char *dest, const char *src);
// 功能:把src拷贝给dest,相当于给dest赋值
// 返回值:dest的首地址,链式调用

char str[100] = "hello";
printf("strcpy=%s\n",strcpy(str,"world"));
#include <string.h>
char *strcat(char *dest, const char *src);
// 功能:把src追加到dest的末尾,相当于+=
// 返回值:dest的首地址,链式调用、
char str[100] = "hello";
printf("strcat=%s\n",strcat(str,"world"));
#include <string.h>
int strcmp(const char *s1, const char *s2);
// 功能:比较两个字符串,根据字典序,谁出现早谁小,一旦比较出结果,立即返回
// 返回值:
//       s1 > s2   正数
//       s1 == s2   0
//       s1 < s2   负数
printf("strcmp=%d\n",strcmp("abc","adc"));
#include <stdlib.h>
int atoi(const char *nptr);
// 功能:把字符串转换成int类型
#include <stdlib.h>
double atof(const char *nptr);
// 功能:把字符串转换成double类型
#include <string.h>
char *strstr(const char *haystack, const char *needle);
// 功能:在haystack中查找是否存在子串needle
// 返回值:needle在haystack中第一次出现的位置,如果找不到返回NULL
#include <stdio.h>
int sprintf(char *str, const char *format, ...);
// 功能:把任意类型的数据转换成字符串并输入到str中

int main(int argc,const char* argv[])
{
    int num = 10086;
    double d = 3.14;
    char str[100] = {};
    sprintf(str,"num=%d d=%lf\n",num,d);
    printf("%s",str);
}

#include <stdio.h>
int sscanf(const char *str, const char *format, ...);
// 功能:从字符串中解析出各种类型的数据,并储存到对应的变量中

int main(int argc,const char* argv[])
{
    char* str = "1997 7 1.11";
    int year = 0,month = 0;
    double d = 0;
    sscanf(str,"%d %d %lf",&year,&month,&d);
    printf("%d %d %lf\n",year,month,d);
}
#include <string.h>
void *memcpy(void *dest, const void *src, size_t n);
// 功能:把src内存的数据拷贝n个字节到desk中

int arr1[10] = {1,2,3,4,5,6,7,8,9,10};
int* p = malloc(40);
memcpy(p,arr1,40);// 拷贝的类型要相同

//memcpy/memmove/memset/memcmp(按字节比较)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值