C++ string类使用


1.string类简介

cplusplus.com : String class

头文件<string>中包含以下类模板:

template<class charT,
	      class traits = char_traits<charT>, // basic_string::traits_type           
		  class Alloc = allocator<charT>     // basic_string::allocator_type
> 
class basic_string; // basic_string类模板

template <class charT> struct char_traits;

string是basic_string类模板的实例化:

typedef basic_string<char> string;

// 此外还实例化了以下宽度不同的字符串处理类
typedef basic_string<wchar_t> wstring;
typedef basic_string<char32_t> u32string;
typedef basic_string<char16_t> u16string;

静态成员变量npos

size_t是无符号整型,-1补码便是无符号整型最大值

static const size_t npos = -1;

2.构造函数

//default (1) 
string();

//copy (2)	
string (const string& str);

//substring (3)	
string (const string& str, size_t pos, size_t len = npos);

//from c-string (4)	
string (const char* s);

//from buffer (5)	
string (const char* s, size_t n);

//fill (6)	
string (size_t n, char c);

//range (7)	迭代器 [first, last)
template <class InputIterator>  string  (InputIterator first, InputIterator last);

//initializer list (8)	
string (initializer_list<char> il);

//move (9)	
string (string&& str) noexcept;

示例:

// string constructor
#include <iostream>
#include <string>

int main ()
{
  std::string s0 ("Initial string");

  // constructors used in the same order as described above:
  std::string s1;
  std::string s2 (s0);
  std::string s3 (s0, 8, 3);
  std::string s4 ("A character sequence");
  std::string s5 ("Another character sequence", 12);
  std::string s6a (10, 'x');
  std::string s6b (10, 42);      // 42 is the ASCII code for '*'
  std::string s7 (s0.begin(), s0.begin()+7);

  std::cout << "s1: " << s1 << "\ns2: " << s2 << "\ns3: " << s3;
  std::cout << "\ns4: " << s4 << "\ns5: " << s5 << "\ns6a: " << s6a;
  std::cout << "\ns6b: " << s6b << "\ns7: " << s7 << '\n';
  return 0;
}

输出结果:

/*
s1: 
s2: Initial string
s3: str
s4: A character sequence
s5: Another char
s6a: xxxxxxxxxx
s6b: **********
s7: Initial
*/

3.string成员的访问:[] at back front

1.下标+[]

// 普通string对象
char& operator[] (size_t pos);
// const string对象
const char& operator[] (size_t pos) const;

// string::operator[]
#include <iostream>
#include <string>

int main ()
{
  std::string str ("Test string");
  for (int i=0; i<str.length(); ++i)
  {
    std::cout << str[i];
  }
  return 0;
}

2.at方法:pos越界将会抛出out_of_range异常。

// 普通string对象
char& at (size_t pos);
// const string对象
const char& at (size_t pos) const;

// string::at
#include <iostream>
#include <string>

int main ()
{
  std::string str ("Test string");
  for (unsigned i=0; i<str.length(); ++i)
  {
    std::cout << str.at(i);
  }
  return 0;
}

3.back()尾部元素:不应该再空string对象中调用

char& back();
const char& back() const;

// string::back
#include <iostream>
#include <string>

int main ()
{
  std::string str ("hello world.");
  str.back() = '!';
  std::cout << str << '\n'; // hello world!
  return 0;
}

4.front()头部元素:不应该再空string对象中调用

char& front();
const char& front() const;

// string::front
#include <iostream>
#include <string>

int main ()
{
  std::string str ("test string");
  str.front() = 'T';
  std::cout << str << '\n'; // Test string
  return 0;
}

4.容量相关

size length max_size capacity

// 返回以字节为单位的字符串长度
// 有效字符的长度 不包括\0
size_t size() const noexcept;
size_t length() const noexcept;
// 返回string对象可以到达的最大长度
size_t max_size() const noexcept;
// 返回当前为字符串分配的存储空间的大小,以字节为单位
// 有效字符的可用空间,不包括'\0'
size_t capacity() const noexcept;

// comparing size, length, capacity and max_size
#include <iostream>
#include <string>

int main ()
{
    std::string str ("Test string");
    std::cout << "size: " << str.size() << "\n"; // 11 
    std::cout << "length: " << str.length() << "\n"; // 11
    std::cout << "capacity: " << str.capacity() << "\n"; // 15
    std::cout << "max_size: " << str.max_size() << "\n"; // 4294967291
    return 0;
}

可以通过调用成员reserve显式地更改字符串的容量。

reserve resize

// 如果n比capacity大,则扩容capacity到n
// 其余情况,容器实现是否缩容。
// 该函数对length没影响
void reserve (size_t n = 0);

// string::reserve
#include <iostream>
#include <fstream>
#include <string>

int main ()
{
    std::string str;
    
    std::ifstream file ("test.txt",std::ios::in|std::ios::ate);
    if (file) {
        std::ifstream::streampos filesize = file.tellg();
        str.reserve(filesize);

        file.seekg(0);
        while (!file.eof())
        {
            str += file.get();
        }
        std::cout << str;
    }
    return 0;
}
// 如果n比当前length小,自动截断到n个字符
// 如果n比当前length大,则在尾部插入字符c直到当前length为n
void resize (size_t n);
void resize (size_t n, char c);


// resizing string
#include <iostream>
#include <string>

int main ()
{
    std::string str ("I like to code in C");
    std::cout << str << '\n';

    unsigned sz = str.size();

    str.resize (sz+2,'+');
    std::cout << str << '\n'; // I like to code in C++

    str.resize (14);
    std::cout << str << '\n'; // I like to code
    return 0;
}

clear 从控制台输入字符到string对象

// 清空字符串内容 变为空串(length为0)
void clear() noexcept;

// string::clear
#include <iostream>
#include <string>

int main ()
{
    char c;
    std::string str;
    std::cout << "Please type some lines of text. Enter a dot (.) to finish:\n";
    do {
        c = std::cin.get();
        str += c;
        if (c=='\n')
        {
            std::cout << str;
            str.clear();
        }
    } while (c!='.');
    return 0;
}

empty 按行读取内容到string对象

// 判断是否是空串(length是0)
bool empty() const noexcept;

// string::empty
#include <iostream>
#include <string>

int main ()
{
    std::string content;
    std::string line;
    std::cout << "Please introduce a text. Enter an empty line to finish:\n";
    do {
        getline(std::cin,line);
        content += line + '\n';
    } while (!line.empty());
    std::cout << "The text you introduced was:\n" << content;
    return 0;
}

shrink_to_fit

随着string对象插入字符的增加,capacity会变大,其他api一般不会缩容减少capacity,原因是再次申请空间拷贝数据影响效率。使用shrink_to_fit可以使capacity自适应size大小

// 减少string的capacity使之适应size大小 使capacity略大于size
// 不改变length
void shrink_to_fit();


// string::shrink_to_fit
#include <iostream>
#include <string>

int main ()
{
    std::string str (100,'x');
    std::cout << "1. capacity of str: " << str.capacity() << '\n'; // 100

    str.resize(10);
    std::cout << "2. capacity of str: " << str.capacity() << '\n'; // 100

    str.shrink_to_fit();
    std::cout << "3. capacity of str: " << str.capacity() << '\n'; // 10

    return 0;
}

5.修改元素

+=运算符

在尾部增加字符(序列)

//string (1)	
string& operator+= (const string& str);

//c-string (2)	
string& operator+= (const char* s);

//character (3)	
string& operator+= (char c);

//initializer list (4)	
string& operator+= (initializer_list<char> il);


// string::operator+=
#include <iostream>
#include <string>

int main ()
{
    std::string name ("John");
    std::string family ("Smith");
    name += " K. ";         // c-string
    name += family;         // string
    name += '\n';           // character

    std::cout << name; // John K. Smith
    return 0;
}

append

尾部增加字符(串)

//string (1)	
string& append (const string& str);

//substring (2)	
string& append (const string& str, size_t subpos, size_t sublen);

//c-string (3)	
string& append (const char* s);

//buffer (4)	
string& append (const char* s, size_t n);

//fill (5)	
string& append (size_t n, char c);

//range (6)	
template <class InputIterator>   
string& append (InputIterator first, InputIterator last);

//initializer list(7)	
string& append (initializer_list<char> il);
// appending to string
#include <iostream>
#include <string>

int main ()
{
    std::string str;
    std::string str2="Writing ";
    std::string str3="print 10 and then 5 more";

    // used in the same order as described above:
    str.append(str2);                       // "Writing "
    str.append(str3,6,3);                   // "10 "
    str.append("dots are cool",5);          // "dots "
    str.append("here: ");                   // "here: "
    str.append(10u,'.');                    // ".........."
    str.append(str3.begin()+8,str3.end());  // " and then 5 more"
    str.append<int>(5,0x2E);                // "....."

    // Writing 10 dots here: .......... and then 5 more.....
    std::cout << str << '\n';
    return 0;
}

push_back

尾部插入一个字符

void push_back (char c);


// string::push_back
#include <iostream>
#include <fstream>
#include <string>

int main ()
{
    std::string str;
    std::ifstream file ("test.txt",std::ios::in);
    if (file) {
        while (!file.eof()) str.push_back(file.get());
    }
    std::cout << str << '\n';
    return 0;
}

assign

给字符串赋一个新的值,替换掉当前值。

//string (1)	
string& assign (const string& str);

//substring (2)	
string& assign (const string& str, size_t subpos, size_t sublen);

//c-string (3)	
string& assign (const char* s);

//buffer (4)	
string& assign (const char* s, size_t n);

//fill (5)	
string& assign (size_t n, char c);

//range (6)	
template <class InputIterator>
string& assign (InputIterator first, InputIterator last);

//initializer list(7)	
string& assign (initializer_list<char> il);

//move (8)	
string& assign (string&& str) noexcept;
// string::assign
#include <iostream>
#include <string>

int main ()
{
    std::string str;
    std::string base="The quick brown fox jumps over a lazy dog.";

    // used in the same order as described above:

    str.assign(base);
    std::cout << str << '\n';

    str.assign(base,10,9);
    std::cout << str << '\n';         // "brown fox"

    str.assign("pangrams are cool",7);
    std::cout << str << '\n';         // "pangram"

    str.assign("c-string");
    std::cout << str << '\n';         // "c-string"

    str.assign(10,'*');
    std::cout << str << '\n';         // "**********"

    str.assign<int>(10,0x2D);
    std::cout << str << '\n';         // "----------"

    str.assign(base.begin()+16,base.end()-12);
    std::cout << str << '\n';         // "fox jumps over"

    return 0;
}
/*
The quick brown fox jumps over a lazy dog.
brown fox
pangram
c-string
**********
----------
fox jumps over
*/

insert

//string (1)	
string& insert (size_t pos, const string& str);

//substring (2)	
string& insert (size_t pos, const string& str, size_t subpos, size_t sublen);

//c-string (3)	
string& insert (size_t pos, const char* s);

//buffer (4)	
string& insert (size_t pos, const char* s, size_t n);

//fill (5)	
string& insert (size_t pos, size_t n, char c);
iterator insert(const_iterator p, size_t n, char c);

//single character (6)	
iterator insert (const_iterator p, char c);

//range (7)	
template <class InputIterator>
iterator insert (iterator p, InputIterator first, InputIterator last);

//initializer list (8)	
string& insert (const_iterator p, initializer_list<char> il);
// inserting into a string
#include <iostream>
#include <string>

int main()
{
	std::string str = "to be question";
	std::string str2 = "the ";
	std::string str3 = "or not to be";
	std::string::iterator it;

	// used in the same order as described above:
	str.insert(6, str2);                 // to be (the )question
	str.insert(6, str3, 3, 4);           // to be (not )the question
	str.insert(10, "that is cool", 8);   // to be not (that is )the question
	str.insert(10, "to be ");            // to be not (to be )that is the question
	str.insert(15, 1, ':');              // to be not to be(:) that is the question
	it = str.insert(str.begin() + 5, ','); // to be(,) not to be: that is the question
	str.insert(str.end(), 3, '.');       // to be, not to be: that is the question(...)
	str.insert(it + 2, str3.begin(), str3.begin() + 3); // (or )

    // to be, or not to be: that is the question...
	std::cout << str << '\n';
	return 0;
}

erase

删除string长度,length减少

//sequence (1)	
string& erase (size_t pos = 0, size_t len = npos);

//character (2)	删除p指向的字符
iterator erase (const_iterator p);

//range (3)	删除[first,last)
iterator erase (const_iterator first, const_iterator last);
// string::erase
#include <iostream>
#include <string>

int main()
{
	std::string str("This is an example sentence.");
	std::cout << str << '\n';
	// "This is an example sentence."

	str.erase(10, 8); 
	std::cout << str << '\n'; // "This is an sentence."

	str.erase(str.begin() + 9);
	std::cout << str << '\n'; // "This is a sentence."

	str.erase(str.begin() + 5, str.end() - 9);
	std::cout << str << '\n'; // "This sentence."
	return 0;
}

replace

替换从pos开始len长度的字符,或者范围在[i1, i2)的内容。

//string(1) 从pos开始copy str 
string& replace(size_t pos, size_t len, const string& str); 
string& replace(const_iterator i1, const_iterator i2, const string& str);

//substring(2) 从pos开始copy str
string& replace(size_t pos, size_t len, const string& str, size_t subpos, size_t sublen);

//c - string(3) copy s指向的字符串
string & replace(size_t pos, size_t len, const char* s); 
string& replace(const_iterator i1, const_iterator i2, const char* s);

//buffer(4) copy s指向的n个字符
string& replace(size_t pos, size_t len, const char* s, size_t n); string& replace(const_iterator i1, const_iterator i2, const char* s, size_t n);

//fill(5)
string& replace(size_t pos, size_t len, size_t n, char c); string& replace(const_iterator i1, const_iterator i2, size_t n, char c);

//range(6)
template <class InputIterator>
string& replace(const_iterator i1, const_iterator i2, InputIterator first, InputIterator last);

//initializer list(7)
string& replace(const_iterator i1, const_iterator i2, initializer_list<char> il);
// replacing in a string
#include <iostream>
#include <string>

int main()
{
	std::string base = "this is a test string.";
	std::string str2 = "n example";
	std::string str3 = "sample phrase";
	std::string str4 = "useful.";

	// replace signatures used in the same order as described above:

	// Using positions:                 0123456789*123456789*12345
	std::string str = base;           // "this is a test string."
	str.replace(9, 5, str2);          // "this is an example string." (1)
	str.replace(19, 6, str3, 7, 6);     // "this is an example phrase." (2)
	str.replace(8, 10, "just a");     // "this is just a phrase."     (3)
	str.replace(8, 6, "a shorty", 7);  // "this is a short phrase."    (4)
	str.replace(22, 1, 3, '!');        // "this is a short phrase!!!"  (5)

	// Using iterators:                                               0123456789*123456789*
	str.replace(str.begin(), str.end() - 3, str3);                    // "sample phrase!!!"      (1)
	str.replace(str.begin(), str.begin() + 6, "replace");             // "replace phrase!!!"     (3)
	str.replace(str.begin() + 8, str.begin() + 14, "is coolness", 7);    // "replace is cool!!!"    (4)
	str.replace(str.begin() + 12, str.end() - 4, 4, 'o');                // "replace is cooool!!!"  (5)
	str.replace(str.begin() + 11, str.end(), str4.begin(), str4.end());// "replace is useful."    (6)
	
    std::cout << str << '\n'; // replace is useful.

	return 0;
}

swap

void swap (string& str);

// swap strings
#include <iostream>
#include <string>

int main()
{
	std::string buyer("money");
	std::string seller("goods");

	std::cout << "Before the swap, buyer has " << buyer;
	std::cout << " and seller has " << seller << '\n';

	seller.swap(buyer);

	std::cout << " After the swap, buyer has " << buyer;
	std::cout << " and seller has " << seller << '\n';

	return 0;
}
/*
Before the swap, buyer has money and seller has goods
 After the swap, buyer has goods and seller has money
*/

pop_back

删除尾部元素

void pop_back();

// string::pop_back
#include <iostream>
#include <string>

int main()
{
	std::string str("hello world!");
	str.pop_back();
	std::cout << str << '\n'; // hello world
	return 0;
}

6.字符串操作

c_str data

返回一个指向以空结尾的字符序列的指针。

const char* c_str() const noexcept;

const char* data() const noexcept;
// strings and c-strings
#include <iostream>
#include <cstring>
#include <string>

int main()
{
	std::string str("Please split this sentence into tokens");

	char* cstr = new char[str.length() + 1];
	std::strcpy(cstr, str.c_str());

	// cstr now contains a c-string copy of str

	char* p = std::strtok(cstr, " ");
	while (p != 0)
	{
		std::cout << p << '\n';
		p = std::strtok(NULL, " ");
	}

	delete[] cstr;
	return 0;
}
/*
Please
split
this
sentence
into
tokens
*/
// string::data
#include <iostream>
#include <string>
#include <cstring>

int main()
{
	int length;

	std::string str = "Test string";
	char* cstr = "Test string";

	if (str.length() == std::strlen(cstr))
	{
		std::cout << "str and cstr have the same length.\n";

		if (memcmp(cstr, str.data(), str.length()) == 0)
			std::cout << "str and cstr have the same content.\n";
	}
	return 0;
}
/*
str and cstr have the same length.
str and cstr have the same content.
*/

copy

将当前字符串从pos开始的len长度的子串,拷贝到s指向的数组中。不会在拷贝内容的末尾加\0

size_t copy (char* s, size_t len, size_t pos = 0) const;


// string::copy
#include <iostream>
#include <string>

int main()
{
	char buffer[20];
	std::string str("Test string...");
	std::size_t length = str.copy(buffer, 6, 5); // 返回6
	buffer[length] = '\0';
    
    // buffer contains: string
	std::cout << "buffer contains: " << buffer << '\n';
	return 0;
}

find rfind

从当前字符串的pos位置查找str第一次出现的地方的下标

//string(1)
size_t find(const string& str, size_t pos = 0) const noexcept;

//c - string(2)
size_t find(const char* s, size_t pos = 0) const;

//buffer(3)
size_t find(const char* s, size_t pos, size_type n) const;

//character(4)
size_t find(char c, size_t pos = 0) const noexcept;
// string::find
#include <iostream>       // std::cout
#include <string>         // std::string

int main()
{
	std::string str("There are two needles in this haystack with needles.");
	std::string str2("needle");

	// different member versions of find in the same order as above:
	std::size_t found = str.find(str2);
	if (found != std::string::npos)
		std::cout << "first 'needle' found at: " << found << '\n';

	found = str.find("needles are small", found + 1, 6);
	if (found != std::string::npos)
		std::cout << "second 'needle' found at: " << found << '\n';

	found = str.find("haystack");
	if (found != std::string::npos)
		std::cout << "'haystack' also found at: " << found << '\n';

	found = str.find('.');
	if (found != std::string::npos)
		std::cout << "Period found at: " << found << '\n';

	// let's replace the first needle:
	str.replace(str.find(str2), str2.length(), "preposition");
	std::cout << str << '\n';

	return 0;
}
/*
first 'needle' found at: 14
second 'needle' found at: 44
'haystack' also found at: 30
Period found at: 51
There are two prepositions in this haystack with needles.
*/
// string::rfind
#include <iostream>
#include <string>
#include <cstddef>

int main()
{
	std::string str("The sixth sick sheik's sixth sheep's sick.");
	std::string key("sixth");

	std::size_t found = str.rfind(key);
	if (found != std::string::npos)
		str.replace(found, key.length(), "seventh");

	std::cout << str << '\n';

	return 0;
}
/*
The sixth sick sheik's seventh sheep's sick.
*/

find_first_of find_last_of

应该为find_any_of,找到任何一个:

上面代码中,使用find_first_of从前向后找到字符串中包含aeiou中任何一个就返回。

// string::find_first_of
#include <iostream>       // std::cout
#include <string>         // std::string
#include <cstddef>        // std::size_t

int main ()
{
  std::string str ("Please, replace the vowels in this sentence by asterisks.");
  std::size_t found = str.find_first_of("aeiou");
  while (found!=std::string::npos)
  {
    str[found]='*';
    found=str.find_first_of("aeiou",found+1);
  }

  std::cout << str << '\n';

  return 0;
}
/*
Pl**s*, r*pl*c* th* v*w*ls *n th*s s*nt*nc* by *st*r*sks.
*/
// string::find_last_of
#include <iostream>       // std::cout
#include <string>         // std::string
#include <cstddef>         // std::size_t

void SplitFilename(const std::string& str)
{
	std::cout << "Splitting: " << str << '\n';
	std::size_t found = str.find_last_of("/\\");
	std::cout << " path: " << str.substr(0, found) << '\n';
	std::cout << " file: " << str.substr(found + 1) << '\n';
}

int main()
{
	std::string str1("/usr/bin/man");
	std::string str2("c:\\windows\\winhelp.exe");

	SplitFilename(str1);
	SplitFilename(str2);

	return 0;
}
/*
Splitting: /usr/bin/man
 path: /usr/bin
 file: man
Splitting: c:\windows\winhelp.exe
 path: c:\windows
 file: winhelp.exe
*/

substr

string substr (size_t pos = 0, size_t len = npos) const;

返回从pos开始len长度的字串。

// string::substr
#include <iostream>
#include <string>

int main()
{
	std::string str = "We think in generalities, but we live in details.";
	// (quoting Alfred N. Whitehead)

	std::string str2 = str.substr(3, 5);     // "think"

	std::size_t pos = str.find("live");      // position of "live" in str

	std::string str3 = str.substr(pos);     // get from "live" to the end

	std::cout << str2 << ' ' << str3 << '\n';

	return 0;
}
/*
think live in details.
*/

compare

//string(1)
int compare(const string& str) const noexcept;

//substrings(2) 从pos开始len长度的子串和str比较
int compare(size_t pos, size_t len, const string& str) const;
int compare(size_t pos, size_t len, const string& str, size_t subpos, size_t sublen) const;

//c - string(3)
int compare(const char* s) const;
int compare(size_t pos, size_t len, const char* s) const;

//buffer(4)
int compare(size_t pos, size_t len, const char* s, size_t n) const;
// comparing apples with apples
#include <iostream>
#include <string>

int main()
{
	std::string str1("green apple");
	std::string str2("red apple");

	if (str1.compare(str2) != 0)
		std::cout << str1 << " is not " << str2 << '\n';

	if (str1.compare(6, 5, "apple") == 0)
		std::cout << "still, " << str1 << " is an apple\n";

	if (str2.compare(str2.size() - 5, 5, "apple") == 0)
		std::cout << "and " << str2 << " is also an apple\n";

	if (str1.compare(6, 5, str2, 4, 5) == 0)
		std::cout << "therefore, both are apples\n";

	return 0;
}
/*
green apple is not red apple
still, green apple is an apple
and red apple is also an apple
therefore, both are apples
*/

7.参考

cpluscplus.com : < string >

cpluscplus.com : string

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

shlyyy

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值