string和c字符串(char*, char[])

string和c字符串(char*, char[])

1. 前言:

在写一个字符串分隔函数时遇到了关于string和c字符串的问题,函数如下:

//从一行中分隔出单词
vector<string> split(const string &line) {
    vector<string> words;
    auto word_begin = line.begin();
    auto iter = line.begin();
    while(iter != line.end()) {
        //单词内容
        if(*iter >= 'A' && *iter <= 'Z'){
            iter++;
            continue;
        }
        else if(*iter >= 'a' && *iter <= 'z'){
            iter++;
            continue;
        }
        else if(*iter >= '0' && *iter <= '9'){
            iter++;
            continue;
        }
        else if(*iter == '@' || *iter == '_' || *iter == '.'){
            iter++;
            continue;
        }
        else{//分隔符
            if(iter != word_begin) {//存入单词
                string tmp;
                tmp.insert(tmp.begin(), word_begin, iter);
                words.push_back(tmp);   //insert插入不包括迭代器指向的最后一个元素
                iter++;                 //即插入[word_begin,iter)范围内的元素
                word_begin = iter;      //要保存部分分隔符就注释iter++
                }i                      //不要让其跳过分隔符
            else{ //非空格存入,空格跳过,递增迭代器
                //if(*iter != ' '){
                //    string tmp(1, *iter);
                //    words.push_back(tmp);
                //}
                iter++;
                word_begin = iter;
            }
        }
    }
    return words;
}

有两种方式来存放分隔后的字符串,vectorvector,这两种不同的方涉及到了string和char*的相互转换。

2. 基础

c字符串:字符构成的序列

单引号为单个字符,如:'c'。双引号为字符串,以'\0'结尾,如:"s"。c字符串char*和char[]两种形式,char*以'\0'结束,char[]可以不以'\0'结束。c字符串的长度可以通过strlen()来求(在头文件中),strlen()函数会求从开始到第一个遇到'\0'之间的字符个数(不包括'\0')。char*与char[]也并不相同,虽然char[]是指向字符串的首地址,当作指针来使用,但与指针仍有区别。可以用char[]来初始化char*,却不能用char*来初始化char[]。sizeof(char*)sizeof(char[])并不相同,前者
返回指针内存大小,后者返回数组内存大小,即类型大小×数组容量。

char *p = "string";
//s[6] = "string";报错,初始化时,字符串太长,"string"末尾默认有'\0',为7个字符
char s[6] = {'s', 't', 'r', 'i', 'n', 'g'};
char a[] = "string";            //包含'\0'
//char a[] = s;                 //错误
char *b = a;                    //正确
cout << strlen(p) << endl;      //输出6
cout << strlen(s) << endl;      //此处没有'\0',计数到内存中第一个遇到的'\0'处
cout << sizeof(p) << endl;      //输出8
cout << sizeof(s) << endl;      //输出6 char为1 1×6
cout << sizeof(a) << endl;      //输出7
cout << sizeof(b) << endl;      //输出8
cout << sizeof(a)/sizeof(char); //输出7,数组容量

string:以字符为元素的一种容器,一种类。

与char*不同string不一定以NULL('\0')结束,可以通过s.begin()和s.end()访问元素,也可以通过下标访问。string中单个元素为char类型,可通过s.length()获取string长度

string s = "string";
for(auto c : s){
    cout << typeid(c).name() << endl;   //输出为c,char类型,实际上c为char&
}
cout << s.length() << endl;               //输出为6

3.内容

(1). 将c字符串转换成string可以通过string的构造函数string(const char *s);string (int n, char c);来完成。

char *p = "string";
char s[6] = {'s', 't', 'r', 'i', 'n', 'g'};
char a[] = "string";
char *b = a;
string str1(p);
string str2(a);
string str3(b);
string str4(s);

(2). 将string转换成char*可以调用const char *c_str() constconst char *data()const两个函数。前者是一个以NULL('\0')结束的c字符串,后者是一个以非NULL('\0')结束的c字符串。但只能转换成const char*

string s = "string";
const char *s1 = s.c_str();
const char *s2 = s.data();

也可以通过函数int copy(char *s, int n, int pos) const来转换,该函数将string
以下标pos开始的n个字符拷贝到以s为起始位置的字符数组中。

string s1 = "string";
string s2 = "string_copy";
char a[s2.length() + 1] = "";
char *p = a;
s1.copy(a, s1.length(), 0);
for (int i = 0; i < s1.length(); i++)
    cout << a[i];                   //输出string
cout << endl;
s2.copy(p, s2.length(), 0);
int i = 0;
while(i < s2.length()) {
    cout << *p;                     //输出string_copy
    p++;
    i++;
}
cout << endl;
for (int i = 0; i < s2.length(); i++)
    cout << a[i];                   //输出string_copy
cout << endl;
return 0;

(3). 字符串分隔函数的另一种写法:

//从一行中分隔出单词
vector<string> split(const char *line) {
    char word[strlen(line) + 1] = "";   //用来存放单词的临时数组
    size_t pos = 0;                     //下标
    vector<string> words;
    while(*line != 0) {             //*line为char类型,比较时按ASCII码比较,而0为空字符。
        //单词内容
        if(*line >= 'A' && *line <= 'Z'){
            word[pos] = *line;
            pos++;
            line++;
            continue;
        }
        else if(*line >= 'a' && *line <= 'z'){
            word[pos] = *line;
            pos++;
            line++;
            continue;
        }
        else if(*line >= '0' && *line <= '9'){
            word[pos] = *line;
            pos++;
            line++;
            continue;
        }
        else if(*line == '@' || *line == '_' || *line == '.'){
            word[pos] = *line;
            pos++;
            line++;
            continue;
        }
        else{//分隔符
            if(word[0] != 0){       //存在单词,存入vector容器
                string tmp(word);
                words.push_back(tmp);
                memset(word,0,sizeof(word));    //清空word,以便下次存放
                pos = 0;                        //重置下标
            }
            line ++;
        }
    }
    return words;
}

(4). 用iostringstream做简单的字符串分隔:

int main(int argc, char *argv[]){
    string line;
    getline(cin,line);
    string word;
    istringstream input(line);
    while(input >> word){
        //cout << word << endl;
        ostringstream os;
        os << word;
        cout << os.str() << endl;
    }
    return 0;
}
//输入hello,string this is a test
//输出:
//hello,string
//this
//is
//a
//test

你可能感兴趣的:(C++)