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指向的值

在这个例子中,ptr1ptr2都是指向常量字符的指针,你可以改变它们的指向,但不能通过它们来改变字符的值。

这两种写法的唯一区别在于风格:一些人更喜欢const char*,因为它更接近英语的读法(一个指向字符的常量指针),而另一些人更喜欢char const*,因为它更接近C++的解析方式(一个指向常量字符的指针)。

如果你想要一个指针,既不能改变它的指向,也不能改变它指向的值,你可以使用const char* str ="Hello"