带有中文的字符串各个字符的获取c++程序

简单易懂,上代码:


#include <iostream>
#include <cstring>
#include <string>
#include <cstdlib>
#include <vector>
using namespace std;

class CStr{
    char *c;
    typedef struct {
        int start;
        bool isChinese;
    } counter;
    int cLen;
    vector<counter> cs;
    void calculate(){
        cLen = sizeof("你") - 1;
        int size = 0;
        for(int i = 0; i < getlen();){
            counter ic;
            ic.start = i;
            //根据第一个字符是否为负数判断是否为中文。。这个不知道是不是万金油,但是大多数情况应该可以应付。
            if(c[i] < 0){
                ic.isChinese = true;
                i += cLen;
            }else{
                ic.isChinese = false;
                i++;
            }
            cs.push_back(ic);
        }
    }
public:
    CStr(const char *cc){
        cout<<"构造"<<endl;
        c = new char[strlen(cc) + 1];
        strcpy(c, cc);
        calculate();
    }
    CStr(const CStr& s){//copy
        cout<<"copy"<<endl;
        c = new char[s.getlen() + 1];
        strcpy(c, s.getstr());
        calculate();
    }
    const CStr& operator =(const CStr& s){
        cout<<"= operator"<<endl;
        if(&s == this) return s;
        cs.clear();
        delete []c;
        c = new char[s.getlen() +1];
        strcpy(c, s.getstr());
        calculate();
        return *this;
    }
    const char *getstr() const{return c;}
    int getlen() const{
        return strlen(c);
    }
    int getsize() const{
        return cs.size();
    }
    string substr(int start, int len) const{
	    if(start + len > cs.size()){
		    len = cs.size() - start;
	    }
	    int realStart = 0, realLen = 0;

	    for(int j = 0; j < start;j++){
		    if(cs[j].isChinese){
			    realStart += cLen;
		    }else{
			    realStart += 1;
		    }
	    }
	    for(int i = start; i < start + len; i++){
		    if(cs[i].isChinese){
			    realLen += cLen;
		    }else{
			    realLen += 1;
		    }
	    }

	    return string(c).substr(realStart, realLen);
    }
    string get(int i)const{
        if(i > getsize()){
            cout<<"error in get "<<endl;
            return string("error");
        }
        const counter &cc = cs[i];
        char *r = NULL;
        int len = 0;
        if(cc.isChinese){
            r = new char[cLen + 1];
            len = cLen;
        }else{
            r = new char[2];
            len = 1;
        }
        memcpy(r, c + cc.start, len);
        r[len] = '\0';
        string rs = r;
        delete[]r;
        return rs;
    }

    void printBytes(const char *start, const char *end) const{//debug
        int i = 0;
        do{
            cout<<(int)*(start+i)<<"\t";
        }while(start+(++i) < end);
        cout<<endl;
    }
    void traversal() const {//debug
        for(int i = 0; i < getsize(); i++){
            cout<<get(i)<<" ";
            //printBytes(get(i), get(i) + strlen(get(i)));
        }
        cout<<endl;
    }
    virtual ~CStr(){
        delete []c;
    }
};

int main(){
    CStr str = "中所节快乐阿ajskd~123。1~。31kla加咖啡";
    str.traversal();
    cout<<"str.substr(2,3) = "<<str.substr(2,3)<<endl;
    
    CStr s1 = str;//copy
    s1.traversal();
    cout<<"str.substr(2,4) ="<<str.substr(2,4)<<endl;
    
    s1 = str;// =
    s1.traversal();
    cout<<"str.substr(2,10) ="<<str.substr(2,10)<<endl;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值