字符串向量和数组C++

Posted wanluToPro

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了字符串向量和数组C++相关的知识,希望对你有一定的参考价值。

第3章 字符串、向量和数组

命名空间的using声明

目前为止我们使用的库函数基本都属于命名空间std,如std::cin 、std::cout。其中::我们称其为作用域操作符,编译起编译起从操作符左侧名字的作用域寻找右侧那个名字。

但是上面很繁琐、允许我们通过using声明

//example1.cpp
#include<iostream>
using std::cout;
using std::endl;
int main(int argc,char**argv)
    const char*name="gaowanlu";
    cout<<name<<endl;//gaowanlu
    std::cout<<name<<std::endl;//gaowanlu
    return 0;

这样在这个cpp内使用std::cout与std::endl时就可以省略写std::了,但是仍然允许我们显式指定其明明空间

头文件不应包含using声明

头文件一般不使用using声明,因为头文件的内容会被拷贝到,include它的cpp去,如果头文件有using声明,则那些cpp内也会有这些using声明,可能会引起明明冲突

//example2.h
#ifndef __EXAMPLE2_H__
#define __EXAMPLE2_H__

using std::cout;

#endif

当第4行代码不被注释掉时,则会引入using std::cout; 当main函数内使用cout,编译器则不会知道知道我们要使用std::cout还是自定义的cout,进而产生命名出错

总之不要在头文件内使用using声明

//example2.cpp
#include<iostream>
#include<cstdio>

//#include"./example2.h"

int cout()
    printf("printf hallo");


int main(int argc,char**argv)
    cout();//printf hallo
    return 0;


标准库类型string

首先要导入 #include<string> 其命名空间为 std::string

在C语言中是没有字符串类型的,但可以用字符数组进行存储,以 \\0 表示字符串结束

定义和初始化string对象

6种直接初始化方式、1种拷贝初始化方式

    1、string s5;          //空串
    2、string s6(s5);      // s6为s5的副本 也就是拷贝s5到s6
    3、string s7 = "ak47"; // s7为字面值的副本
    4、string s8 = s7;
    5、string s9("94");
    6、string s10(1, 'h');
    7、string s11=std::string("hello world");

样例程序

//example3.cpp
#include <iostream>
#include <string>
using std::cout;
using std::endl;
using std::string;
int main(int argc, char **argv)

    string s1; //默认初始化为空字符串
    string s2 = "gaowanlu";
    string s3 = s2; // s3为s2内容的副本
    string s4(4, 'a');
    cout << s2 << endl; // gaowanlu
    cout << s3 << endl; // gaownalu
    cout << s4 << endl; // aaaa

    // string的7种初始化方式
    // 6种直接初始化方式
    string s5;          //空串
    string s6(s5);      // s6为s5的副本 也就是拷贝s5到s6
    string s7 = "ak47"; // s7为字面值的副本
    string s8 = s7;
    string s9("94");
    string s10(1, 'h');
    cout << s5 << endl;  //
    cout << s6 << endl;  //
    cout << s7 << endl;  // ak47
    cout << s8 << endl;  // ak47
    cout << s8 << endl;  // ak47
    cout << s9 << endl;  // 94
    cout << s10 << endl; // h
    // 1种拷贝初始化
    string s11 = std::string("hello world");
    cout << s11 << endl; // hello world
    return 0;

string对象上的操作

在C++中string是一种标准库里的对象,其支持丰富的操作

//example4.cpp
#include <iostream>
using namespace std;
int main(int argc, char **argv)

    string s1("hello world");
    string s2 = "hello world";

支持写入到输出流 outputstream<<str

    cout << s1 << endl; // hello world

同理支持从输入流写入到字符串 inputstream>>s1

    // cin>>s1;

从输入流中读取一行到字符串getline(inputstream,str)

    // getline(cin, s1); //这里我们使用标准输入流
    // cout << s1 << endl;

检测字符串是否为空字符串 str.empty()

    cout << s1.empty() << endl; // false 则s1不为空

获取字符串长度

    cout << s1.size() << endl; // 11

获取第n个字符的引用 n 0开始为第一个字符

    char &ch = s1[0];
    ch = 'p';
    s1[3] = 'k';
    cout << s1 << endl; // pelko world

字符串拼接

    string s3 = s1 + s2;
    s3+="";//支持+=
    cout << s3 << endl;          // pelko worldhello world
    cout << s3 + "HAHA" << endl; // pelko worldhello worldHAHA

字符串复制

    string s4 = s3;

s4与s3没有关系,只是内容相同,它们的数据存放在不同的内存上面

    cout << s4 << endl; // pelko worldhello world

字符串的比较

    cout << (s3 == s4) << endl; // 1 即true
    cout << (s3 != s4) << endl; // 0 即false

字典顺序比较

    string s5 = "abcd";
    string s6 = "abda";
    cout << (s5 < s6) << endl;  // 1 abcd abda c<d
    cout << (s5 <= s6) << endl; // 1 abcd abda c<=d
    cout << (s5 > s6) << endl;  // 0 abcd abda c<d
    cout << (s5 >= s6) << endl; // 0 abcd abda c<=d
    return 0;

getline函数的返回值

//example5.cpp
#include <iostream>
#include <string>
using namespace std;
int main(int argc, char **argv)

    string s1;
    while (getline(cin, s1)) // getline返回文件到达末尾也就是cin流的内容是否全部到头
    
        cout << s1 << endl;
    
    //只有退出程序时cin才会关闭以至于getline返回false
    //与其类似的操作还有
    /*
    while (cin >> s1)
    
        cout << s1 << endl;
    */
    return 0;

std::string::size_type类型

其字符串size()方法返回值用什么类型存储比较好,C++为我们提供了std::string::sizetype类型

//example6.cpp
#include <iostream>
using namespace std;
int main(int argc, char **argv)

    std::string s1("hello");
    std::string::size_type s1_length = s1.size();
    cout << s1_length << endl;                      // 5
    cout << sizeof(std::string::size_type) << endl; // 4
    
    // str.size()返回一个无符号整数
    //当然我们可以使用我们前面学到的auto 与 decltype
    auto l1 = s1.size();
    decltype(s1.size()) l2 = s1.size();
    cout << l1 << endl; // 5
    cout << l2 << endl; // 5

    //当然可以用unsigned 或者 int
    unsigned l3 = s1.size();
    int l4 = s1.size();
    cout << l3 << " " << l4 << endl; // 5 5
    return 0;

字符串相加要注意的事

字符串字面值不能与字符串字面值相加、相加对于string对象有效,即+号的左右至少有一个string对象

//example7.cpp
#include <iostream>
#include <string>
using namespace std;
int main(int argc, char **argv)

    //字符串对象与字符串对象相加返回字符串对象
    //字符串对象与字面值相加返回字符串对象
    //字面值与字面值相加发生错误

    // string s1 = "12" + "sdc";
    //  invalid operands of types 'const char [3]' and 'const char [4]' to binary 'operator+'
    //字面值被作为const char[] 处理

    string s2 = "a";
    s2 = s2 + " b " + "c ";
    //(s2+" b ")+"c "
    cout << s2 << endl; // a b c

    return 0;

这是为什么呢,C++为了与C语言兼容,所以C++语言中的字符串并不是作为std::stirng对象处理的

处理string对象中的字符

#include<cctype>

isalnum(c);//当c是字母或数字时为真
isalpha(c);//当c是字母时返回真
iscntrl(c);//当c是控制字符时为真
isdigit(c);//当c是数字时为真
isgraph(c);//当c不是空格但可以打印时为真
islower(c);//当c是小写字母时为真
isprint(c);//当c是可打印字符时为真(即c是空格或c具有可视化形式)
ispunct(c);//当c是标点符号时为真(不是控制字符、数字、字母、可打印空白)
isspace(c);//当c是空白时为真(即是空格、横向制表符、纵向制表符、回车符、换行符、进纸符)
isupper(c);//当c为大写字母时为真
isxdigit(c);//当c是十六进制数字时为真
tolower(c);//如果c是大写字母,输出对应的小写字母,否则原样输出c
toupper(c);//如果是小写字母、输出对应的大写字母,否则原样输出

如toupper使用

//exmaple8.cpp
#include <iostream>
#include <cctype>
using namespace std;
int main(int argc, char **argv)

    string s1 = "abc";
    s1[1] = toupper(s1[1]);
    cout << s1 << endl; // aBc
    return 0;

遍历字符串字符

C++对于字符串的遍历支持迭代器模式

//example9.cpp
#include <iostream>
#include <string>
#include <cctype>
using namespace std;
int main(int argc, char **argv)

    string s1 = "abc";
    for (char &ch : s1)
    
        cout << ch << endl; // abc
        ch = toupper(ch);
    
    cout << s1 << endl; // ABC
    //当然我们可以使用auto
    for (auto ch : s1)
    
        cout << ch << endl; // ABC
        ch = tolower(ch);
    
    cout << s1 << endl; // ABC
    //可见auto是类型char而不是char&
    return 0;

下标的随机访问

//example10.cpp
#include <iostream>
#include <string>
using namespace std;
int main(int argc, char **argv)

    string s1 = "abcd";
    //例如访问最后一个字符
    if (s1.empty() == false)
    
        cout << s1[s1.size() - 1] << endl; // d
    
    //字符下标索引从0开始
    // a b c d
    // 0 1 2 3
    return 0;

标准库类型vector

std::vector表示对象的集合,其所有元素类型相同,每个集合中对每个对象有唯一的对应索引,用于随机访问,因为vector容纳其他对象,所以也被称为容器。其背后有一个重要的概念叫做类模板的东西在支持着它,类模板是C++特性之一,其非常强大。

std::vector<T> T可以为任意数据类型

定义和初始化vector

七种初始化方式 以T为int为例

vector<int> v1;                //空vector
vector<int> v2(v1);            //拷贝v1 v2拥有v1元素的副本
vector<int> v3 = v2;           //拷贝v2 v3拥有v2元素的副本
vector<int> v4(5, 10);         // vector内有5个10
vector<int> v5(5);             // 5个int类型初始默认值元素即有5个0
vector<int> v6 = 1, 2, 3, 4; // 元素序列为1 2 3 4
vector<int> v71, 2, 3, 4;    //等价于vector<int> v6=1, 2, 3, 4

使用样例

//example11.cpp
#include <iostream>
#include <vector>
using std::cout;
using std::endl;
using std::vector;
void printIntVector(vector<int> &v);
int main(int argc, char **argv)

    vector<int> v1;                //空vector
    vector<int> v2(v1);            //拷贝v1 v2拥有v1元素的副本
    vector<int> v3 = v2;           //拷贝v2 v3拥有v2元素的副本
    vector<int> v4(5, 10);         // vector内有5个10
    vector<int> v5(5);             // 5个int类型初始默认值元素即有5个0
    vector<int> v6 = 1, 2, 3, 4; // 元素序列为1 2 3 4
    vector<int> v71, 2, 3, 4;    //等价于vector<int> v6=1, 2, 3, 4
    printIntVector(v1);            //
    printIntVector(v2);            //
    printIntVector(v3);            //
    printIntVector(v4);            // 10 10 10 10 10
    printIntVector(v5);            // 0 0 0 0 0
    printIntVector(v6);            // 1 2 3 4
    printIntVector(v7);            // 1 2 3 4
    return 0;


/**
 * @brief 打印vector<int>元素
 *
 * @param v vector<int>
 */
void printIntVector(vector<int> &v)

    for (int i = 0; i < v.size(); i++)
    
        cout << v[i] << " ";
    
    cout << endl;

向vector内添加元素

vector允许我么在定义初始化后,对其内部的元素再进行操作,例如向其后面追加元素

//example12.cpp
#include <iostream>
#include <string>
#include <vector>
using namespace std;
void printStringVector(vector<string> &v)

    for (int i = 0; i < v.size(); i++)
    
        cout << v[i] << " ";
    
    cout << endl;

int main(int argc, char **argv)

    vector<string> v1 = "a", "b", "c";
    printStringVector(v1); // a b c
    v1.push_back("d");
    v1.push_back("e");
    printStringVector(v1);  // a b c d e
    vector<string> v2 = v1; //拷贝v1到v2
    v2[0] = "p";
    printStringVector(v1); // a b c d e
    printStringVector(v2); // p b c d e
    return 0;

vector其他操作

vector提供的方法与string提供的方法类似,可以向上翻到string进行对比学习

vector.empty()、vector.size()、vector.push_back(T)、下标引用、拷贝、列表替换、==、!=、<、<=、>、>=

//example13.cpp
#include <iostream>
#include <string>
#include <vector>
using namespace std;
int main(int argc, char **argv)

    vector<char> v;
    v.empty();               //如果v不含任何元素,则返回真,否则返回假
    v.size();                //返回元素个数
    v.push_back('a');        //向末尾追加元素
    char &ch_index_0 = v[0]; //获取第n个位置元素的引用
    vector<char> v1;
    v1 = v;               //将v内的元素拷贝给v1
    v1 = 'a', 'b', 'c'; //使用列表替换vector内存储的内容
    vector<char> v2(v1);
    //当vector二者元素个数相同,且每个位置上一一对应都是相等的则为true否则为false
    cout << (v1 == v2) << endl; // 1
    cout << (v1 != v2) << endl; // 0
    //二者元素数量不同或者对应位置有元素不相等返回true,否则返回false
    v1 = 'a', 'b', 'c';
    v2 = 'a', 'd';
    //支持字典顺序比较
    cout << (v1 <= v2) << endl; // 1
    cout << (v1 < v2) << endl;  // 1
    cout << (v1 >= v2) << endl; // 0
    cout << (v1 > v2) << endl;  // 0
    return 0;
C++ 字符串向量和数组的一些术语

C++ 字符串向量和数组的一些术语

C++ 字符串向量和数组的一些术语

C++ 字符串向量和数组的一些术语

c++核心-字符串向量和数组及指针详解

C++11 字符数组初始化和字符串字面量