分享

学习C++

 雪柳花明 2016-11-06

学习C++ -> 字符串



一、字符串的概念
    用双引号括起来的一串字符称为字符串, 例如 "abc"、"Hello, world!"。C++延续了C语言中的做法, 将字符串使用字符型(char)一维数组来存放, 在存放字符串时, 编译器会在字符串结束的位置自动添加"\0", "\0"是 ASCII 码值为0的转义符, 它是字符串的结束标志, 对于这种存放方式, 称它为字符数组更为合适
    
    在字符串中, 有效字符的个数称为字符串的长度, 例如字符串"abc"的长度为3, 但它所占的字节数为4字节, 因为编译器会在结束时自动添加一个 "\0", 也就是说, 定义长度为n的字符型一维数组只能存放下n-1个字符, 否则将无法存放结束标识"\0", 在某些情况下将导致字符串无法正常使用, 严重时可导致一些未知的错误。
    

二、字符串的实现
    字符型一维数组的定义同普通数组一样, 只要把数组的数组类型改为 char 型即可, 例如:

        char a[10] ;
        char b[20] ;

    在定义完一维字符数组时也可以对其进行初始化, 初始化分为两种方式:
        1>.逐个字符进行初始化, 例如:

            char a[6] = { 'H', 'e', 'l', 'l', 'o', '\0' } ;

 
        此时a[0]中存放'H'字符, a[1]中存放'e'字符..., 这里的大括号不能省略, 同时初始化的字符个数也不能超过数组定义的长度, 不过在初始化时字符数组的元素个数声明可以省略, 这样编译器会自动计算好后面初始化中所需的数组长度, 如:

            char a[] = { 'H', 'e', 'l', 'l', 'o', '\0' } ;

 
        像下面对字符数组的初始化都是错误的:

            char a[6] = { 'H', 'e', 'l', 'l', 'o', ',', 'w', 'o', 'r', 'l', 'd', '\0' } ;        //错误! 初始值的长度超过了数组定义的长度
            char a[6] = 'H', 'e', 'l', 'l', 'o', '\0' ;        //错误! 没有使用大括号 

 
            
        2>. 使用字符串常量初始化方式, 例如:

            char a[6] = {"Hello"} ;

 
            由于编译器会自动在字符串末尾添加'\0'字符, 所以字符数组a的各元素存放的内容依次为: 'H', 'e', 'l', 'l', 'o', '\0'
            在上述初始化形式中, 大括号可以省略, 并且在初始化时数组元素的长度声明也可以省略, 编译器会根据初始化值中的字符个数(包括'\0')自动计算数组所需的元素个数, 以下声明都是正确的:

                char a[6] = "Hello" ;
                char a[] = "Hello" ;

 




三、字符串的使用
    举例一: 定义一个字符串并输出

复制代码
#include<iostream>

using namespace std ;

int main()
{
    char a[] = "Hello" ;    //定义并初始化一个字符串·
    cout<< a ;              //输出该一维字符数组中的字符串

    return 0 ;
}
复制代码

 
    此外, 字符数组还可以进行逐个输出或者逐个替换操作。


    举例二: 输出其中某一个字符, 并将字符数组中的某个字符替换成其他字符。

复制代码
#include<iostream>

using namespace std ;

int main()
{
    char a[] = "Hello" ;    //定义并初始化一个字符串·
    cout<< a[2] <<endl ;    //输出a[2]中保存的字符
    a[0] = 'W' ;            //将a[0]中的'H'替换成'W'
    cout<<a ;               //全部输出

    return 0 ;
}
复制代码

 



四、字符串的输入
    1>. 使用cin进行输入, 举例:

复制代码
#include<iostream>
using namespace std ;

int main()
{
    char a[50] ;
    cin>>a ;        //输入字符串a
    cout<<a ;       //输入后进行输出
    return 0 ;
}
复制代码

 
    使用cin进行输入主要使用在字符串输入过程没有空白符(空格、tab)的情况下, 当存输入过程中按下空格键或tab键时cin就会默认输入结束, 当再按下回车进行时, 也只存空白符前面的内容, 例如:

hello world            <-这里输入的是带有空格的 hello world
hello                <-可以看到, 输出时只剩下了空格前面的hello
Process returned 0 (0x0)   execution time : 7.578 s
Press any key to continue.

 
        注意: 如果连续输入的字符数超过了49个, 则可能会引起内存错误!
    


    2>. cin.get() 函数
        如果想连空格一起输入到字符数组中可以使用 cin.get() 函数, 举例:

复制代码
#include<iostream>
using namespace std ;

int main()
{
    char a[50] ;
    cin.get(a, 50) ;        //输入字符串a
    cout<<a ;               //输入后进行输出
    return 0 ;
}
复制代码

    在 cin.get(a, 50) ; 这行, a是要输入字符串的数组名, 后面的50为最长允许获取多少字符, 当值为50时表示只获取输入的前49个字符, 当值为10时表示只获取输入的前10个字符。
    


    3>. cin.getline() 函数
        cin.getling() 函数也可起到输入一行并包含空格的作用, 使用举例:

复制代码
#include<iostream>
using namespace std ;

int main()
{
    char a[50] ;
    cin.getline(a, 50) ;        //输入字符串a
    cout<<a ;       //输入后进行输出
    return 0 ;
}
复制代码

 



    4>. cin.get() 与 cin.getline() 的不同之处
        虽说这两个函数都能够用来输入带有空格的字符串, 但还是有不同之处的, 两个函数都用于读入一行输入, 直至遇到换行符, 但是 getline() 函数会将换行符从输入队列中提取出来并抛弃掉, 而 get() 函数不会将换行符从输入队列中提取并抛弃掉, 这乍一看区别不大, 实际上在有连续几行的输入时这将会对输入结果产生很大的影响。举例:

复制代码
#include<iostream>
using namespace std ;

int main()
{
    char a[50], b[50] ;     //定义两个字符数组

    cout<<"请输入字符串一:" ;
    cin.get(a, 50) ;        //输入字符串a
    cout<<"请输入字符串二:" ;
    cin.get(b, 50) ;        //输入字符串b

    cout<<a ;               //输入后进行输出
    cout<<b ;
    return 0 ;
}
复制代码

 
运行后的输入以及输出:

请输入字符串一:hello my name
请输入字符串二:hello my name
Process returned 0 (0x0)   execution time : 7.031 s
Press any key to continue.


    如果我们自己编译运行后可以发现, 当我们输入完毕第一行字符串, 还没来得及输入第二行时程序就已经运行结束了, 这就是因为 get() 函数会将换行符留在输入队列所致, 当输入完第一行时我们按下回车, get 函数获取输入的内容, 并把换行符留在了输入队列, 当执行到 cin.get(b, 50) ; 时正好他得到的第一个字符不是用户的输入, 而是遗留在上一次输入的换行符, 这样它就误认为用户输入以及结束了而自动结束输入。

    由于 get() 函数不会抛弃输入队列中的换行符, 因此在使用 get() 函数进行输入时可以使用一个较为完善的输入方式:

        cin.get(数组名, 允许长度).get() ;

    这样当第一个 get() 获取到用户输入并存放到字符数组后, 第二个 get() 会负责把换行符提取出来, 相当于抛弃掉, 这样在下一行使用函数进行输入时就不会再出现还没有输入程序就已经默认为输入已经结束的情况。
    


    
五、字符串处理函数
    数组不能整体的进行加减乘除比较等操作, 例如以下操作都是错误的:

        char a[50] = "Hello" ;
        char b[50] = "world" ;
        if(a == b)        //错误!
        a += b ;        //错误!
        a = a + "abc" ;    //错误!

 


    可以看出, 在字符串操作上比较的不方便, 为了方便编程的进行, 在C++的标准库里给我们提供好了一些能够对字符串方便操作的函数, 我们只需要调用函数就行了, 要使用这些函数, 需要包含头文件 cstring

        #include<cstring>

    一些常用的字符串处理函数如下:

操作 
函数原型说明
取得字符串长度 
size_t strlen(数组名)不包括结束标志'\0'
将源字符数组中的字符串复制到目标数组char *strcpy(目标数组, 源数组名)目标数组的大小应不小于源字符串
字符串大小比较int strcmp(字符串1, 字符串2)相等返回0, 字符串1大于字符串2返回正数, 否则返回一个负数
将两个字符串连接起来char *strcat(字符串1, 字符串2)将字符串2连接到字符串1后面, 字符串1必须有足够的剩余位置容纳字符串2
将字符串中的小写字符全部转成大写char *strupr(数组名) 
将字符串中的大写字符全部转成小写char *strlwr(数组名) 


    
    

 

 

 

 

 

  需要说明的是关于字符串的大小比较, 字符串的大小比较不是比较其长度, 而是比较从左向右依次比较每个字符的ASCII的值的大小, 如果第一个字符串的第一个字符的ASCII值大于第二个就说明字符串1大于字符串2, 依次类推。

  字符串处理函数使用举例: 测量字符串的长度并将该字符串全部转成大写后输出:

复制代码
#include<iostream>
#include<cstring>
using namespace std ;

int main()
{
    char a[50] = "Hello, I am C++ !" ;
    int n ;         //用来保存字符串的长度值
    n = strlen(a) ; //测量字符串长度
    cout<<n<<endl ; //输出长度

    strupr(a) ;     //将字符串全部转为大写
    cout<<a ;       //输出转换后的字符串
    return 0 ;
}
复制代码

 




--------------------


    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多