【问题标题】:How do I change the case of a string in C++?如何在 C++ 中更改字符串的大小写?
【发布时间】:2011-05-04 07:45:44
【问题描述】:

我有一个可能包含数字以及大小写字母的字符串。我需要将所有大写字母转换为小写,反之亦然。怎么办?

【问题讨论】:

  • 这是一道作业题吗?
  • 哈哈是的。但是,我想出了如何使用 Matthew Iselins 的建议来解决这个问题。
  • for(char &c:str) c^=32;

标签: c++ string case


【解决方案1】:

您可以遍历字符串并从每个字母字符中添加或减去适当的数字,以便将 ASCII 值解析为相反大小写的 ASCII 值。

【讨论】:

  • 如果你打算那样做,你还不如翻转比特..我忘记它是哪一个,但其中一个会交换案例。
【解决方案2】:

迭代字符串并使用isupper() 来确定每个字符是否为大写。如果是大写,则使用tolower() 将其转换为小写。如果不是大写,请使用toupper() 将其转换为大写。

【讨论】:

    【解决方案3】:

    这是一种无需提升的方法:

    #include <string>
    #include <algorithm>
    #include <cctype>
    #include <iostream>
    
    char change_case (char c) {
        if (std::isupper(c)) 
            return std::tolower(c); 
        else
            return std::toupper(c); 
    }
    
    int main() {
        std::string str;
        str = "hEllo world";
        std::transform(str.begin(), str.end(), str.begin(), change_case);
        std::cout << str;
        return 0;
    }
    

    【讨论】:

    • 次要 nitpick - change_case 而不是 swap_letters?
    【解决方案4】:
    char *str = "this is a test string";
    while(*str != '\0') {
        if(*str <= 'Z' && *str >= 'A') {
           *str += 32;
        }
        if(*str >= 'a' && *str <= 'z') {
           *str -= 32;
        }
     str++;
    }
    

    根本不安全,只是给你一个想法。 这可能对这个作业很有帮助:

    【讨论】:

    • 这不是一个合适的 C++ 答案,imo。
    • 我同意,这不适用于 unicode 或任何其他非 ASCI 字符,但如果他理解这段代码背后的想法,那么添加对其他任何字符的支持将是一项微不足道的任务字符集,保护它,防止堆损坏等。
    • 如果没有 else 抛出,这会将大写转换为小写,然后将其更改回大写。另外,为什么不使用字符常量('a','z','A','Z')以获得更好的可读性?
    • @PigBen,它不会将大写转换回小写,因为光标会将其位置提前 1。
    • -1。 char * 和处理它的 C 函数(如 strXXX、printf、scanf 等)已经造成了世界上 99% 的错误。不要在 C++ 中使用它!
    【解决方案5】:

    您也可以翻转 32 位:因此适用于 ASCII 字符:

    char flipcase(char x)
    {
       if( ::isalpha(x) )
       {
          return x ^ 32;
       }
    }
    

    您也可以使用表格。然后创建一个静态表

    char flipcase( char x )
    {
       return fliptable[x];
    }
    

    后一种方法的优点是也可以用于外来字符集,只要它们不是多字节的——它就不起作用了。您可以使用您使用的任何字符集为 wchar_t 字符制作一个类似的表。如果字符的 sizeof 不超过 2,则存储表需要使用少量内存,尽管对于 UTF-32 会使用太多并且查找时间很短。当然,在现实中,您会为每个角色及其特征存储一个小结构。

    使用上述任何一种方法,您都可以使用 std::transform。

    现在真正聪明的一点是:std::transform 可以使用类(函子)以及普通函数。因此,对于多字节字符,只要替换字符始终具有相同的第一个元素,我们就可以存储状态。如果不是这种情况,则转换将无法与常规迭代器一起使用。但是,您可以编写一个自定义迭代器来处理多字节字符串,该字符串一次迭代一个可打印的字符(迭代器必须取消对表示符号的多字节字符的引用)。

    【讨论】:

      【解决方案6】:
      #include <iostream>
      #include <string>
      #include <cctype>
      
      using namespace std;
      
      int main(){
          //Changecase to Uppercase
          string var = "This is a String.";
          for (unsigned int i = 0; i < var.length(); i++){
              if (islower(var[i]))
                  var[i] = toupper(var[i]);
          }
          cout << var << endl;
          /*
          Output:
          THIS IS A STRING.
          */
          //Changecase to Lowercase
          var = "This is a String.";
          for (unsigned int i = 0; i < var.length(); i++){
              if (isupper(var[i]))
                  var[i] = tolower(var[i]);
          }
          cout << var << endl;
          /*
          Output:
          this is a string.
          */
          //Flip the case
          var = "This is a String.";
          for (unsigned int i = 0; i < var.length(); i++){
              if (isupper(var[i]))
                  var[i] = tolower(var[i]);
              else
                  var[i] = toupper(var[i]);
          }
          cout << var << endl;
          /*
          Output:
          tHIS IS A sTRING.
          */
      
          system("pause");
          return 0;
      }
      

      【讨论】:

        【解决方案7】:

        执行此操作的标准 C++ 方法如下:

        std::string lower = "this is my string to be uppercased";
        std::locale loc; //get the locale from the system.
        auto facet = std::use_facet<std::ctype<char>>(loc);
        facet.toupper(&lower[0], &lower[0] + lower.length()); //they didn't provide a C++ iterator interface, so pointer arithmetic it is.  
        std::cout << lower << std::endl;
        

        这个输出:

         THIS IS MY STRING TO BE UPPERCASED
        

        还有一个facet.toupper() 用于处理将小写转换为大写,facet.widen 用于从 char 转换为 wchar_t,facet.narrow 用于从 wchar_t 转换为 char。

        【讨论】:

          猜你喜欢
          • 2011-01-07
          • 1970-01-01
          • 1970-01-01
          • 2011-10-11
          • 2011-05-12
          • 2014-04-20
          • 2021-03-30
          • 1970-01-01
          • 2014-02-04
          相关资源
          最近更新 更多