C++中字符串两种表示形式——C风格字符串和string类

C风格字符串

C语言没有原生的字符串类型C风格字符串就是指最后一位为'\0'字符数组,C语言通过字符指针来管理字符串。

使用单引号声明和初始化创建一个 RUNNING 字符串。由于在数组的末尾存储了空字符,所以字符数组的大小比单词 RUNNING 的字符数多一个。

char site[8] = {
    
    'R', 'U', 'N', 'N', 'I', 'N', 'G', '\0'};
char str[] = {
    
     'p', 'r', 'o', 'g', 'r', 'a', 'm', '\0' };

使用双引号赋值有两种语法。这两种存储结构是一样的,都是依靠字符数组进行存储的。

char site[] = "RUNNING";
char* site = "RUNNING";

但是在VS2019中不支持第二种赋值方式

error C2440: “初始化”: 无法从“const char [8]”转换为“char *

相关函数见:https://cplusplus.com/reference/cstring/

  • 复制字符串
char * strcpy ( char * destination, const char * source );
/* strcpy example */
#include <stdio.h>
#include <string.h>

int main()
{
    
    
	char str1[] = "Sample string";
	char str2[40];
	char str3[40];
	strcpy(str2, str1);
	strcpy(str3, "copy successful");
	printf("str1: %s\nstr2: %s\nstr3: %s\n", str1, str2, str3);
	return 0;
}

输出结果

str1: Sample string
str2: Sample string
str3: copy successful
  • 拼接字符串
char * strcat ( char * destination, const char * source );
/* strcat example */
#include <stdio.h>
#include <string.h>

int main()
{
    
    
	char str[80];
	strcpy(str, "these ");
	strcat(str, "strings ");
	strcat(str, "are ");
	strcat(str, "concatenated.");
	puts(str);
	return 0;
}

输出结果

these strings are concatenated.
  • 比较字符串
int strcmp ( const char * str1, const char * str2 );
#include <stdio.h>
#include <string.h>

int main()
{
    
    
    char key[] = "apple";
    char buffer[80];
    do {
    
    
        printf("Guess my favorite fruit? ");
        fflush(stdout);
        scanf("%79s", buffer);
    } while (strcmp(key, buffer) != 0);
    puts("Correct answer!");
    return 0;
}
  • 定位子串
const char * strstr ( const char * str1, const char * str2 );
      char * strstr (       char * str1, const char * str2 );
/* strstr example */
#include <stdio.h>
#include <string.h>

int main()
{
    
    
    char str[] = "This is a simple string";
    char* pch;
    pch = strstr(str, "simple");
    if (pch != NULL)
        strncpy(pch, "sample", 6);
    puts(str);
    return 0;
}

输出结果

This is a sample string
  • 获取字符串长度
size_t strlen ( const char * str );
/* strlen example */
#include <stdio.h>
#include <string.h>

int main()
{
    
    
	char szInput[256];
	printf("Enter a sentence: ");
	gets(szInput);
	printf("The sentence entered is %u characters long.\n", (unsigned)strlen(szInput));
	return 0;
}

细心的话,会发现返回值是size_t类型,它是个什么东西?

基本无符号整数类型之一的别名。它是一种能够以字节表示任何对象大小的类型: size_t 是 sizeof 运算符返回的类型,在标准库中广泛用于表示大小和计数。

String类

  • 字符串初始化,C++11标准有以下几种方式
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)			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
  • 返回字符串的长度
size_t size() const noexcept;
size_t length() const noexcept;
#include <iostream>
#include <string>

int main()
{
    
    
	std::string str("Test string");
	std::cout << "The size of str is " << str.size() << " bytes.\n";
	std::cout << "The size of str is " << str.length() << " bytes.\n";
	return 0;
}

输出结果

The size of str is 11 bytes.
The size of str is 11 bytes.
  • 调整字符串长度
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';

	size_t sz = str.size();

	str.resize(sz + 2, '+');
	std::cout << str << '\n';

	str.resize(13);
	std::cout << str << '\n';
	return 0;
}

输出结果

I like to code in C
I like to code in C++
I like to cod
  • 字符串的容量
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";
  std::cout << "length: " << str.length() << "\n";
  std::cout << "capacity: " << str.capacity() << "\n";
  std::cout << "max_size: " << str.max_size() << "\n";
  return 0;
}

输出结果

size: 11
length: 11
capacity: 15
max_size: 9223372036854775807
  • 更改容量
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;
}
  • 清空字符串
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;
}
  • 字符串判空
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;
}

测试输出

Please introduce a text. Enter an empty line to finish:
running

The text you introduced was:
running
  • 字符索引operator []
      char& operator[] (size_t pos);
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;
}

输出结果

Test string
  • 字符索引at
      char& at (size_t pos);
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;
}

输出结果

Test string
  • 插入字符串
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 )

	std::cout << str << '\n';
	return 0;
}

输出结果

to be, or not to be: that is the question...
  • 删除字符串
sequence (1)	string& erase (size_t pos = 0, size_t len = npos);
character (2)	iterator erase (const_iterator p);
range (3)		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;
}

输出结果

This is an example sentence.
This is an sentence.
This is a sentence.
This sentence.
  • 转换为C风格字符串
const char* c_str() 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 (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 substr (size_t pos = 0, size_t len = npos) const;
// 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.
  • 常用的非成员函数

字符串拼接

string (1)	
string operator+ (const string& lhs, const string& rhs);
string operator+ (string&&      lhs, string&&      rhs);
string operator+ (string&&      lhs, const string& rhs);
string operator+ (const string& lhs, string&&      rhs);
c-string (2)	
string operator+ (const string& lhs, const char*   rhs);
string operator+ (string&&      lhs, const char*   rhs);
string operator+ (const char*   lhs, const string& rhs);
string operator+ (const char*   lhs, string&&      rhs);
character (3)	
string operator+ (const string& lhs, char          rhs);
string operator+ (string&&      lhs, char          rhs);
string operator+ (char          lhs, const string& rhs);
string operator+ (char          lhs, string&&      rhs);
// concatenating strings
#include <iostream>
#include <string>

int main()
{
    
    
	std::string firstlevel("com");
	std::string secondlevel("cplusplus");
	std::string scheme("http://");
	std::string hostname;
	std::string url;

	hostname = "www." + secondlevel + '.' + firstlevel;
	url = scheme + hostname;

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

	return 0;
}

输出结果

http://www.cplusplus.com

字符串输入

istream& operator>> (istream& is, string& str);
// extract to string
#include <iostream>
#include <string>

int main()
{
    
    
	std::string name;

	std::cout << "Please, enter your name: ";
	std::cin >> name;
	std::cout << "Hello, " << name << "!\n";

	return 0;
}

输出结果

Please, enter your name: sjn
Hello, sjn!

字符串输出

ostream& operator<< (ostream& os, const string& str);
// inserting strings into output streams
#include <iostream>
#include <string>

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

猜你喜欢

转载自blog.csdn.net/Star_ID/article/details/125255924