本篇教程为基础string用法

1、sizeof()与strlen()get()与getline()的区别

两者都能读取一行输入,知道到达换行符,但是getline()将丢弃换行符,而get()会将换行符保留在输入序列中

1
long totals[500] = {0};  //只要显式地将第一个元素初始化为0,然后让编译器将其他元素都初始化为0;如果初始化为1)而不是{0},则第一个元素被设置为1.其他元素都被设置为

再确定存储字符串所需的最短数组时,别忘了将结尾的空字符串计算在内

1
"S" = 'S' + '\0'

==sizeof==运算符指出整个数组的长度,但==strlen()==函数返回的是当前存储在数组中的字符串长度,而不是数组本身的长度。

1
2
3
4
const int Arsize = 15;
char name2[Arsize] = "C++OWboy";
//通过设置符号常量的地址即可对数组长度进行修改
name2[3] = '\0';

strlen()对于未被初始化的数据, 第一个空字符的出现位置是随机的,因此您在运行该程序时,得到的数据长度很可能与此不同

面向行的输入:getline()

getline是istream类的一个类方法

getline()函数每次读取一行。它通过==换行符==来确定行尾,但不保存==换行符==。相反,在存储字符串时,它用空字符来替换换行符。

1
2
3
4
5
#include <istream>
//设要使用gtline(()将姓名读入到一个包含20个元素的nme数组中
//第一个参数是目标数组;第二个参数数组长度
//长度‘20’包含\0
cin.getling(name,20);

面向行的输入:get()

get()会读取换行符(==所输入的[enter]需要一个get()消化==);用不带任何参数的cin.get()调用可读取下一个字符(即使是换行符),因此可以用它来处理换行符,为读取下一行输入做好准备。

String函数用法1

如何消化换行符

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include <iostream>
#include <string>
using namespace std;

int main(int argc,const char* argv[]) {

char charr[20];
string str;
int year;
cout << "请输入年份:";
cin >> year;
cout << "获取char字符串:";
cin.getline(charr, 20);
cout << "获取string字符串:";
getline(cin, str);
cout << "第一次输入为:" << charr << "\t" << "第二次输入为:" << str;


return 0;
}

String函数用法2

运行上述代码可以发现:在输入1997以及回车确定之后,第一个字符串,也就是代码中的cin.getline(charr,20)将回车键吸收并保留,导致第一次getline()直接被调用。所以可以使用get()函数吸收1997之后的换行符;

1
2
3
4
5
6
7
//以下两种方式均可以
//---1---
cin >> year;
cin.get();//句点表示法

//---2---
(cin>>yeat).get();

在添加上述语句之后:便可以正常输入charrstr两个字符串。

String函数用法3

2、string类

1.注意点

1
2
3
//string类位于命名空间std中
#include <string>
using namespace std;
  • 可以使用C-风格字符串来初始化sring 对象。
  • 可以使用cin来将键盘输入存储到sring对象中。
  • 可以使用cout 来显示 string对象。
  • 可以使用数组表示法来访问存储在string对象中的字符。
  1. 在未输入之前,string对象的长度被自动设置为0

  2. ~~~ C++
    //使用以下方法获取string对象的输入
    char charr[20];
    int length = strlen(charr);
    cout << “strlen(charr):” << length << endl;
    getline(cin,str);//此时getline()不是istream中的类方法

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12

    3. 上述代码中的charr由于定义时未初始化,第一个空字符的出现位置是随机的吗,因此在运行上述strlen(charr)时,会得到一个不确定的数值<img src="https://tvax1.sinaimg.cn/large/0072YHp3ly1gjvu4tpiw6j3083011we9.jpg" alt="String函数用法4" width="291" data-width="291" data-height="37">

    ### 2.string类的赋值、拼接和附加

    ~~~ C++
    string str1="hello ";
    string str2="world!";

    string str3 = str1+str2;//str3 = "hello world!"

    str1 += str2; //str1 = "hello world!"

3.其他形式的字符串字面值

除了char类型,C++还有wchar_t;并且C++11新增了char16_t和char32_t 可以创建这些类型的数组和这些类型的字符串面值。C++11分别使用前缀L、u和U表示上述三种字符

1
2
3
wchar_t c1[] = L"first";
char16_t c2[] = u"second";
char32_t c3[] = U"third";

==除了上述之外,C++11还支持Unicode编码,使用前缀u8表示这种类型的字符串面值==

在不使用转移字符时,即保留\n的原样输出是,常规的做法就是“\\\n”输出\n到序列中,但原始字符串将”(和)”用作定界符,并使用前缀 R来标识原始字符串

1
cout << R"(i am a "big"one .)"

上述代码输出为:

i am “big” one.

就不必使用\来表示转义序列。

同时也可以使用自定义定界符控制开始和结尾R”+*(输出内容)+*“

1
cout << R"+*("(how are you?)",i'm fine. )+*"

上述代码输出为:

“(how are you?)”,i’m fine.

需要注意的是,在默认定界符之间可以添加任意数量额基本的字符,但是不包括(空格、左括号、右括号、斜杠和控制字符(如制表符和换行符)),还可以结合着字符串前缀使用,如Ru、UR等

substr(size_type pos,size_type n = npos)函数

返回一个字符串——这是从pos开始,复制n个字符(或到字符串尾部)得到的。

1
2
string messgae ("this is a test string!");
string firstWord(message.substr(0,4))

3、结构体

1.定义

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
//创建结构体
//定义一个student结构体,包括三种类型的变量
struct student{
char name[20];
int age;
bool gender;
};
//还可以在创建的结构体的时候就创建结构变量,同时也可以对变量初始化
struct student{
char name[20];
int age;
bool gender;
}ming_xiao,hua_li=
{
"lihua",
18,
0
};
//还可以声明没有名称的结构体,省略名称就行
struct{
char name[20];
int age;
bool gender;
} Danny; //这样就创建了一个Danny的结构体变量,可以使用Danny.name调用成员变量

2.结构数组

1
2
3
4
5
6
7
8
9
10
11
12
13
//创建结构体
student stu[100];

//stu中的每个元素都是stu对象,可以与成员运算符一起使用
cin >> stu[0].name;
cout << stu[99].age;

//结构数组在定义的时候也可以初始化

student stu[2] ={
{"LiMing"19,1},
{"Danny",21,0}
};