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!