代码之家  ›  专栏  ›  技术社区  ›  Node.JS

将字符的普通迭代器转换为字符串

  •  -1
  • Node.JS  · 技术社区  · 4 年前

    我想知道如何转换字符迭代器 __gnu_cxx::__normal_iterator<char*, std::__cxx11::basic_string<char> > 到C++中的字符串?

    #include <iostream>
    #include <string>
    #include <algorithm>
    using std::string;
    
    #define TO_UPPER(s) (transform((s).begin(), (s).end(), (s).begin(), ::toupper))
    #define TO_LOWER(s) (transform((s).begin(), (s).end(), (s).begin(), ::tolower))
    
    
    int main() {
        string str = "Hello world!";
    
        string result = TO_LOWER(str);
    
        std::cout << result << std::endl;
        return 0;
    }
    

    错误:

    [1/2] Building CXX object CMakeFiles/untitled.dir/main.cpp.o
    FAILED: CMakeFiles/untitled.dir/main.cpp.o 
    /usr/bin/c++   -g -std=gnu++11 -MD -MT CMakeFiles/untitled.dir/main.cpp.o -MF CMakeFiles/untitled.dir/main.cpp.o.d -o CMakeFiles/untitled.dir/main.cpp.o -c /home/amir-pc/CLionProjects/untitled/main.cpp
    /home/amir-pc/CLionProjects/untitled/main.cpp: In function ‘int main()’:
    /home/amir-pc/CLionProjects/untitled/main.cpp:7:31: error: conversion from ‘__gnu_cxx::__normal_iterator<char*, std::__cxx11::basic_string<char> >’ to non-scalar type ‘std::string’ {aka ‘std::__cxx11::basic_string<char>’} requested
        7 | #define TO_LOWER(s) (transform((s).begin(), (s).end(), (s).begin(), ::tolower))
          |                     ~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    /home/amir-pc/CLionProjects/untitled/main.cpp:13:21: note: in expansion of macro ‘TO_LOWER’
       13 |     string result = TO_LOWER(str);
          |                     ^~~~~~~~
    ninja: build stopped: subcommand failed.
    
    2 回复  |  直到 4 年前
        1
  •  6
  •   HolyBlackCat    4 年前

    std::transform 在适当的位置修改容器。您不需要它的返回值,只需读取原始容器即可。

    如果可能的话,也要避免使用宏。偏好函数。

    还要注意 std::toupper 如果给定负字符代码,则会导致未定义的行为。您需要将参数强制转换为 unsigned char 首先要避免这种情况。

    以下是来自 cppreference :

    std::string str_toupper(std::string s) {
        std::transform(s.begin(), s.end(), s.begin(), 
                    // static_cast<int(*)(int)>(std::toupper)         // wrong
                    // [](int c){ return std::toupper(c); }           // wrong
                    // [](char c){ return std::toupper(c); }          // wrong
                       [](unsigned char c){ return std::toupper(c); } // correct
                      );
        return s;
    }
    
        2
  •  0
  •   Vlad from Moscow    4 年前

    这些宏就地更改字符串

    #define TO_UPPER(s) (transform((s).begin(), (s).end(), (s).begin(), ::toupper))
    #define TO_LOWER(s) (transform((s).begin(), (s).end(), (s).begin(), ::tolower))
    

    所以就写吧

    TO_LOWER(str);
    std::cout << str << std::endl;
    

    否则写入

    #include <iterator>
    
    //...
    
    string str = "Hello world!";
    
    string result;
    result.reserve( str.size() );
    
    std::transform( str.begin(), str.end(), std::back_inserter( result ), ::tolower );
    
    std::cout << result << std::endl;
    

    请注意,使用这样的宏是个坏主意。至少你可以声明内联函数。