优秀的编程知识分享平台

网站首页 > 技术文章 正文

C++ 转换字符串(c++字符串转char)

nanyue 2024-08-27 18:11:25 技术文章 6 ℃


std::string 类是一个连续容器,类似于 vector 或数组。它支持 contiguous_iterator 概念以及所有相应的算法。

string 类是 basic_string 的一个特化版本,其类型为 char。这意味着容器的元素类型为 char。还有其他特化版本可用,但 string 是最常见的。

由于它本质上是一个 char 元素的连续容器,因此可以使用 transform() 算法或任何使用 contiguous_iterator 概念的其他技术对 string 进行操作。

如何做……

根据应用程序的不同,有多种转换方法。本示例将探讨其中的几种。

我们将从几个谓词函数开始。谓词函数接受一个转换元素并返回一个相关元素。例如,下面是一个简单的谓词函数,它返回一个大写字符:

char char_upper(const char& c) {  
    return static_cast<char>(std::toupper(c));  
}


这个函数是 std::toupper() 的一个包装器。由于 toupper() 函数返回一个 int,而 string 的元素类型是 char,因此我们不能直接在转换中使用 toupper() 函数。

下面是相应的 char_lower() 函数:

char char_lower(const char& c) {  
    return static_cast<char>(std::tolower(c));  
}


rot13() 函数是一个有趣的转换谓词,用于演示目的。它是一个简单的替换密码,不适合加密,但常用于混淆:

char rot13(const char& x) {  
    auto rot13a = [](char x, char a)->char {  
        return a + (x - a + 13) % 26;  
    };  
  
    if (x >= 'A' && x <= 'Z') return rot13a(x, 'A');  
    if (x >= 'a' && x <= 'z') return rot13a(x, 'a');  
    return x;  
}


我们可以使用这些谓词函数与 transform() 算法:

int main() {  
    string s{ "hello jimi\n" };  
    cout << s;  
  
    std::transform(s.begin(), s.end(), s.begin(), char_upper);  
    cout << s;  
    // ...


transform() 函数对 s 中的每个元素调用 char_upper(),将结果放回 s 中,并将所有字符转换为大写:

输出:

hello jimi  
HELLO JIMI


除了 transform() 之外,我们还可以使用带有谓词函数的简单 for 循环:

for(auto& c : s) c = rot13(c);  
cout << s;


从我们的大写字符串对象开始,结果是:

URYYB WVZV


rot13 密码的一个有趣之处在于它可以自我解密。因为 ASCII 字母表中有 26 个字母,旋转 13 次后再旋转 13 次将得到原始字符串。让我们将其转换为小写并再次使用 rot13 来恢复字符串:

for(auto& c : s) c = rot13(char_lower(c));  
cout << s;


输出:

hello jimi


由于它们的统一接口,谓词函数可以作为彼此的参数进行链接。我们还可以使用 char_lower(rot13(c)) 来获得相同的结果。

如果你的需求对于简单的逐个字符转换来说太复杂,你可以像使用任何连续容器一样使用 string 迭代器。下面是一个简单的函数,它将小写字符串转换为标题大小写(Title Case),即将第一个字符和每个空格后面的字符转换为大写:

string& title_case(string& s) {  
    auto begin = s.begin();  
    auto end = s.end();  
    *begin++ = char_upper(*begin);  // 第一个元素  
    bool space_flag{ false };  
    for(auto it{ begin }; it != end; ++it) {  
        if(*it == ' ') {  
            space_flag = true;  
        } else {  
            if(space_flag) *it = char_upper(*it);  
            space_flag = false;  
        }  
    }  
    return s;  
}


由于它返回转换后字符串的引用,我们可以像这样使用 cout 调用它:

cout << title_case(s);


输出:

Hello Jimi


工作原理……

std::basic_string 类及其特化版本(包括 string)受迭代器支持,这些迭代器完全符合 contiguous_iterator。这意味着任何适用于任何连续容器的技术也适用于 string。

注意:

由于底层数据是 const-qualified,这些转换不适用于 string_view 对象。

最近发表
标签列表