前言

几年前因为竞赛赶鸭子上架匆忙接触C++,主要学习了一些基础用法和部分算法,对诸如指针、字符串等的细节理解不深,而大学期间也没有再投入多少精力研究,所以积累不增反减。由于网上资料多是复制粘贴且不全,所以趁着毕业前还有些时间,参考《C++ Primer Plus》,重新梳理了一下字符串部分,已经尽可能详细囊括了,缺失部分也会逐渐完善。

何为字符串

存储在内存中连续字节中的一系列字符

字符串类型划分

  • C风格(字符数组char[]/指针)
  • C++风格(string)

C风格字符串

格式问题

  • 以空字符(即 ‘\0’,ASCII码为0)结尾,例如:
char a[3]={'a','b','c'};
    // 1.是char数组,但并非字符串
char b[3]={'a','b','\0'};
    // 2.是char数组,也是字符串
// 一些处理字符串的函数如cout,识别到'\0'停止
  • ""声明和键盘读入到数组的,会隐式地加一个'\0'结尾,同时在其后填充若干空字符。定义字符数组时切记预留空字符位置。
char a[4]="hh"
    //内容:{'h','h','\0','\0'}
    //输出:hh
  • 勿混'S'"S"

'S'代表S的ASCII码

“S”实际上代表着字符串“S”的地址

  • 任何由两个空白(空格、回车、换行)分隔的字符串通常可以看作一个字符串,例如以下两个输出等价:
cout<<"Hel"    "lo"<<endl;
cout<<"Hello"<<endl;
// 拼接时第一个字符串的'\0'会被第二个字符串的首位代替

长度:sizeof()和strlen()的区别

  • 前者是指数组长度
  • 后者是指数组第一个'\0'之前字符的个数
cout<<"Hel"    "lo"<<endl;
//输出:15
cout<<"Hello"<<endl;
//输出:12
a[5]='\0';
cout<<strlen(a);
//输出:5
未初始化的字符数组内容是随机的,第一个空字符不一定在哪,所以strlen()未知

读入问题

cin:遇到空白即为单词,空白之后继续放到输入队列

char a[15],b[15];
cin>>a;

cout<<a<<endl;
cin>>b;
cout<<b;
return 0;
// 输入:Hello World hhh
/* 输出:
    Hello
    World!
*/

cin.getline()和cin.get()

介绍

属于istream类,返回的是cin对象,所以可以拼接使用,如cin.get(a,2).get()

cin.getline(要接收输入的变量,接收字符个数,截止符号)
  • 读取换行符或者指定数目字符停止,并抛弃换行符
  • 若第二个变量填20,则最多接收19个字符
  • 第三个变量为空时默认\0
    char a[15],b[15],c[15];
    cin.getline(a,15);
    //输入:aaa aaa
    cout<<"a: "<<a<<endl;
    //输出:aaa aaa
    cin.getline(b,5);
    //输入:bbbbbb
    cout<<"b: "<<b<<endl;
    //输出:bbbb
cin.get()
  • 遇到换行不抛弃,留在输入流
第一种用法与getline类似

用法参考上下文

第二种情况:cin.get() 吃任何一个字符,包括回车
    char a[15],b[15],c[15];
    cin.get(a,15);
    //输入:abcde fghijklmnopqrst
    cout<<"a: "<<a<<endl;
    //输出: a: abcde fghijklm
    cin.get();
    //吃任何一个字符,包括回车
    cin.get(b,15);
    //输入队列非空,无法输入
    cout<<"b: "<<b<<endl;
    //输出: b: opqrst
读入数组长度大于有效长度时的情况
  • 二者在有效长度内都会正常读取
  • 有效长度之外的字符留在输入队列
  • getline()会设置失效符,并关闭后续输入
    char a[15],b[15],c[15];
    cin.get(a,15);
    //输入:abcde fghijklmnopqrst
    cout<<"a: "<<a<<endl;
    //输出: a: abcde fghijklm
    cin.get(b,15);
    //已设置失效位,关闭输入
    cout<<"b: "<<b<<endl;
    //输出: b:
    char a[15],b[15],c[15];
    cin.get(a,15);
    //输入:abcde fghijklmnopqrst
    cout<<"a: "<<a<<endl;
    //输出: a: abcde fghijklm
    cin.get(b,15);
    //输入队列非空,无法输入
    cout<<"b: "<<b<<endl;
    //输出:nopqrst
选择与使用的注意点
  • 建议使用get(),方便观察是否读取完该行所有内容
  • 多行读取/整数字符串交错读取,切记get()吞一下多余换行符,否则下一行字符串是空串

常用函数

  • strcpy(s1,s2) 将s2复制到s1中
  • strcat(s1,s2) 将s2拼接到s1结尾

C++风格字符串

简介

string类的对象,用对象名.方法()来使用。在很多方面,用法与字符数组相同,但是string可以自动调节大小,不必担心越界问题。

赋值、合并和拼接

对于string来说,可以直接操作char[]和string。与此对比,C风格需要诸如strcpy等函数

  • =直接赋值
  • +/+=合并或者拼接

读取问题

cin

与C风格类似,不能读取空格

getline(cin,name)

    string a;
    getline(cin,a);
    //输入:aaa bbb
    cout<<a;
    //输出:aaa bbb
    return 0;

长度

对象.size()确定字符串长度

未初始化的string的size默认是0;与此不同,字符数组的strlen未知
    string a;
    getline(cin,a);
    //输入:aaa bbb
    cout<<a<<' '<<a.size();
    //输出:aaa bbb 7
    return 0;

待补充

未整理完,待补充……

最后修改:2022 年 04 月 23 日
如果觉得我的文章对你有用,请随意赞赏