c++中字符串之string和char
c++ string初始化的几种方式
相对于C#来说,c++中string的初始化方式真的非常多,比如以下都可以用来初始化string:
using namespace std;
int main() {
string str1 = "test01" ;//直接赋值
string str2( 5, 'c' ); // 结果:str2='ccccc',以length为长度的ch的拷贝(即length个ch)
string str3( "hello" );//像调函数一样初始化或赋值
string str4( str3, 0, 2 );//以index为索引开始的子串,长度为length, 或者 以从start到end的元素为初值.
}
字符串拼接
std:string
使用 + 运算符:这是最简单的方法,可以直接将两个字符串拼接在一起。
std::string str1 = "Hello, ";
std::string str2 = "World!";
std::string str3 = str1 + str2; // "Hello, World!"
使用 std::string::operator+=:这个运算符可以用来在字符串的末尾添加另一个字符串。
std::string str = "Hello, ";
str += "World!"; // str 现在是 "Hello, World!"
stringstream
使用 stringstream 类:std::stringstream 类可以用来构建复杂的字符串。你可以像使用流一样使用它,然后使用 str() 成员函数获取结果字符串
#include <sstream>
std::stringstream version;
//拼接后的格式:10.0.19044
version << rtlos.dwMajorVersion <<"." << rtlos.dwMinorVersion<<"."<<rtlos.dwBuildNumber;
std::string str = version.str();
_snprintf
#include <stdio.h>
int main() {
char buffer[50];
int a = 10;
float b = 20.5;
// 使用_snprintf拼接字符串
_snprintf(buffer, sizeof(buffer), "a = %d, b = %.2f", a, b);
printf("%s\n", buffer); // 输出:a = 10, b = 20.50
return 0;
}
char与string转换
string.c_str()转成char*
#include <string>
std::string
find字符串查找
std::string::npos是一个静态常量,表示在std::string中没有找到字符或子字符串的位置。当在std::string中搜索一个字符或子字符串时,如果没有找到,则返回std::string::npos。它的值通常被定义为-1,因此在搜索和替换操作中,可以使用它来检查是否找到了匹配项。
#include <iostream>
#include <string>
int main() {
std::string str = "Hello, World!";
std::size_t found = str.find("World");
if (found != std::string::npos) {
std::cout << "'World' found at: " << found << std::endl;
} else {
std::cout << "'World' not found" << std::endl;
}
found = str.find('o');
if (found != std::string::npos) {
std::cout << "'o' found at: " << found << std::endl;
} else {
std::cout << "'o' not found" << std::endl;
}
return 0;
}
std::unordered_set
std::unordered_set
是C++ STL中提供的一个无序集合容器。它基于哈希表实现,具有常数时间的平均插入、删除和查找操作。与std::set
不同,std::unordered_set
中的元素没有特定的顺序,因此不支持像std::set
那样的排序操作。std::unordered_set
的元素必须是可哈希的,即具有可计算哈希值的类型。常见的可哈希类型包括整数、指针、字符串和自定义类型(需要提供哈希函数和相等比较函数)。以下是一些常用的std::unordered_set
函数: - insert()
:向集合中插入一个元素。 - erase()
:从集合中删除一个元素。 - find()
:查找集合中是否存在某个元素。 - empty()
:检查集合是否为空。 - size()
:返回集合中元素的数量。 - clear()
:清空集合中的所有元素。 使用std::unordered_set
时需要注意的一点是,由于元素的顺序是无序的,因此迭代器不能用于按顺序遍历元素。
compare字符串比较
c++中的string对象的比较,如果是两个string比较,可以用C#那样的 if (str1 == str2)
但如果是比较两个char[],那就不能使用,而是要用strcmp,因为数组中比较的是两个数组的首地址,而不是它们的内容!
例子
#include<iostream>
#include<string>
using namespace std;
int main() {
char a[] = "aaa",b[]="aaa";
string A = "AAA", B = "AAA";
cout <<"*a和*b的值分别是:" <<*a << "," << *b << endl;
cout <<"*“aaa”的值是:"<< *"aaa" << endl;
//错误的比较方法:
cout <<"利用 == 比较a,b两个字符串,结果是(相等为1,不等为0):" <<(a==b) << endl;
//正确的比较方法:
cout << "利用strcmp()比较a,b两个字符串,结果是(相等为0,不等非0):"<<strcmp(a,b) << endl;
cout << "利用 == 比较A,B两个string,结果是(相等为1,不等为0):"<<(A==B) << endl;
cout << "利用compare()比较A,B两个string,结果是(相等为0,不等非0):" << A.compare(B) << endl;
return 0;
}
运行结果
*a和*b的值分别是:a,a
*“aaa”的值是:a
利用 == 比较a,b两个字符串,结果是(相等为1,不等为0):0
利用strcmp()比较a,b两个字符串,结果是(相等为0,不等非0):0
利用 == 比较A,B两个string,结果是(相等为1,不等为0):1
利用compare()比较A,B两个string,结果是(相等为0,不等非0):0
strcmp在gcc/g++中无法编译通过
strcmp在gcc/g++中无法编译通过,但用vs却可以
这可能是因为在GCC/G++编译器中,strcmp
函数是在cstring
头文件中定义的,而在Visual Studio中,strcmp
函数也在string.h
头文件中定义。所以在GCC/G++中,你需要包含cstring
头文件,而不是string.h
。
以下是一个在GCC/G++中可以编译通过的示例:
#include <iostream>
#include <cstring> // 使用这个头文件
int main() {
char str1[] = "Hello";
char str2[] = "Hello";
char str3[] = "World";
if (strcmp(str1, str2) == 0) {
std::cout << "str1 and str2 are equal" << std::endl;
} else {
std::cout << "str1 and str2 are not equal" << std::endl;
}
if (strcmp(str1, str3) == 0) {
std::cout << "str1 and str3 are equal" << std::endl;
} else {
std::cout << "str1 and str3 are not equal" << std::endl;
}
return 0;
}
这个程序在GCC/G++编译器中可以编译通过,并且运行结果与预期相同。
该用string还是char*?
从知乎的一个回答上看到,对于客户端来说,这两者随意用。char*偏C,而string是一个对象
最后总结就是为了兼容性和性能请用char*,char[]内存是连续的(数组是连续的),而且使用C++需要确定数组的长度是连续的
因为vc不同版本会有不兼容性,这个我在学习的时候就遇到了,而且还有一些vc特殊的库,让其在gcc下无法编译通过。
如果遇到运行时出错,建议使用vc6来编译。
为什么底层 C/C++ 代码的 char[] 比 string 多很多? - 知乎 (zhihu.com)
char const*
通过typeid().name()打印出来的类型是:A的类型:int ,B的类型:char const*
char const*
和const char*
在C++中是等价的,它们都表示一个指向常量字符的指针。这意味着你可以改变指针指向的地址,但不能改变指针指向的值。
以下是一个示例:
const char* ptr1;
char const* ptr2;
char c1 = 'A';
ptr1 = &c1; // 这是合法的,可以改变ptr1的指向
// *ptr1 = 'B'; // 这是非法的,不能改变ptr1指向的值
char c2 = 'B';
ptr2 = &c2; // 这是合法的,可以改变ptr2的指向
// *ptr2 = 'A'; // 这是非法的,不能改变ptr2指向的值
在这个例子中,ptr1
和ptr2
都是指向常量字符的指针,你可以改变它们的指向,但不能通过它们来改变字符的值。
这两种写法的唯一区别在于风格:一些人更喜欢const char*
,因为它更接近英语的读法(一个指向字符的常量指针),而另一些人更喜欢char const*
,因为它更接近C++的解析方式(一个指向常量字符的指针)。
如果你想要一个指针,既不能改变它的指向,也不能改变它指向的值,你可以使用const char* str ="Hello"
。