如何将std :: string转换为小写?


777

我想将A转换std::string为小写。我知道该函数tolower(),但是在过去,我对该函数存在问题,无论如何它都不是理想的选择,因为与a std::string一起使用需要对每个字符进行迭代。

有没有一种替代方法可以100%地起作用?


34
在不迭代整个列表的情况下,您如何将列表中的每个元素转换为其他内容?字符串只是字符列表,如果您需要对每个字符应用某些功能,则必须遍历字符串。没办法解决。

14
为什么这个问题会降低评级?我遍历字符串没有问题,但是我想问是否还有其他功能,除了tolower(),toupper()等
。– Konrad

3
如果您具有C样式的char数组,那么我想您可以将ox20202020添加到每个4个字符的块中(假设它们已经全部为大写),一次将4个字符转换为小写。

13
@Dan:如果它们可能已经是小写字母,但肯定是AZ或az,则可以使用0x20进行“或”运算而不是添加。那些聪明的选择-可能是愚蠢的优化之一,几乎是不值得的……
史蒂夫·杰索普

4
我不知道为什么它会被拒绝投票……肯定措辞有些奇怪(因为您必须以某种方式遍历每个项目),但这是一个有效的问题
Warren

Answers:


904

改编自不太常见的问题

#include <algorithm>
#include <cctype>
#include <string>

std::string data = "Abc";
std::transform(data.begin(), data.end(), data.begin(),
    [](unsigned char c){ return std::tolower(c); });

如果没有遍历每个角色,您真的不会逃脱。没有办法知道字符是小写还是大写。

如果您真的讨厌tolower(),这是一种专用的纯ASCII替代方法,我不建议您使用:

char asciitolower(char in) {
    if (in <= 'Z' && in >= 'A')
        return in - ('Z' - 'z');
    return in;
}

std::transform(data.begin(), data.end(), data.begin(), asciitolower);

请注意,tolower()只能执行一个单字节字符替换,这不适用于许多脚本,尤其是在使用像UTF-8这样的多字节编码的情况下。


25
(可能是旧的,所讨论的算法变化不大)// @ Stefan Mai:调用STL算法有什么样的“大量开销”?这些函数相当精简(即,对于循环而言很简单),并且经常内联,因为您很少在同一编译单元中多次调用具有相同模板参数的同一函数。
eq-

257
每当您假设字符为ASCII字符时,上帝就会杀死一只小猫。:(
Brian Gordon

13
您的第一个示例可能具有未定义的行为(传递char::tolower(int)。)您需要确保您不传递负值。
juanchopanza 2014年

37
-1的使用::tolower可能会崩溃,它是用于非ASCII输入的UB。
干杯和健康。-Alf 2014年

7
在降低之前需要使用::来指示它位于最外面的命名空间中。如果您在另一个名称空间中使用此代码,则可能存在tolower的不同定义(可能不相关),最终将导致优先选择:::。
Charles Ofria '16

320

Boost为此提供了一个字符串算法

#include <boost/algorithm/string.hpp>

std::string str = "HELLO, WORLD!";
boost::algorithm::to_lower(str); // modifies str

或者,就地

#include <boost/algorithm/string.hpp>

const std::string str = "HELLO, WORLD!";
const std::string lower_str = boost::algorithm::to_lower_copy(str);

2
我认为这与ASCII输入下没有相同的问题吗?
paulm,2015年

19
非ASCII-7失败。
DevSolar

1
有非原位版本吗?
Ray:

5
@Ray,是的to_lower_copy
smac89 '17

233

tl; dr

使用ICU库如果您不这样做,则在您可能甚至不知道存在的情况下,转换例程将默默中断。


首先,您必须回答一个问题:您的编码std::string什么?是ISO-8859-1吗?还是ISO-8859-8?还是Windows Codepage 1252?您用来转换成小写字母的任何内容都知道吗?(或者,字符超过会失败0x7f吗?)

如果您将UTF-8(8位编码中唯一的明智选择)与std::string用作容器,则您已经在欺骗自己,认为自己仍然可以控制一切,因为您正在容器中存储多字节字符序列那不知道多字节的概念。即使是像.substr()滴答作响的定时炸弹一样简单的事情。(因为拆分多字节序列将导致无效(子)字符串。)

而且,只要您尝试std::toupper( 'ß' )使用任何编码进行类似的操作,将遇到很大的麻烦。(因为用标准库根本不可能做到“正确”,因为标准库只能传递一个结果字符,在"SS"这里不是必需的。)[1]另一个例子是std::tolower( 'I' )根据地区的不同,它会产生不同的结果。在德国,'i'这是正确的;在土耳其,'ı'(拉丁文小写字母I)是预期的结果(同样,以UTF-8编码超过一个字节)。另一个示例是希腊文Sigma,大写'∑',小写'σ'...除了单词结尾处是'ς'

因此,任何一次在一个字符上或更糟的是一次在一个字节上工作的大小写转换都被设计破坏了。

再有就是点的标准库,它能够做,取决于其语言环境的支持你的软件上运行的计算机上...和你做什么,如果它是不是?

因此,您真正要寻找的是一个能够正确处理所有这些问题的字符串类,并且不是任何std::basic_string<>变体

(C ++ 11注:std::u16stringstd::u32string更好的,但还不够完善C ++ 20带来的std::u8string,但这一切都为指定编码在其他许多方面,他们仍然一无所知的Unicode力学,像正常化,整理,...。 )

虽然Boost 看起来不错,但从API角度来看,Boost.Locale基本上是ICU的包装器。如果 Boost是在ICU支持下编译的 ...如果不是,则Boost.Locale限于为标准库编译的语言环境支持。

并相信我,有时 Boost与ICU一起编译可能是一个真正的痛苦。(没有针对Windows的预编译二进制文件,因此您必须将它们与应用程序一起提供,将打开一堆全新的蠕虫病毒……)

因此,我个人建议直接从马口中获得完整的Unicode支持,并直接使用ICU库:

#include <unicode/unistr.h>
#include <unicode/ustream.h>
#include <unicode/locid.h>

#include <iostream>

int main()
{
    /*                          "Odysseus" */
    char const * someString = u8"ΟΔΥΣΣΕΥΣ";
    icu::UnicodeString someUString( someString, "UTF-8" );
    // Setting the locale explicitly here for completeness.
    // Usually you would use the user-specified system locale,
    // which *does* make a difference (see ı vs. i above).
    std::cout << someUString.toLower( "el_GR" ) << "\n";
    std::cout << someUString.toUpper( "el_GR" ) << "\n";
    return 0;
}

编译(在此示例中为G ++):

g++ -Wall example.cpp -licuuc -licuio

这给出:

ὀδυσσεύς

请注意,单词中间的Σ<->σ转换,单词末尾的Σ<->ς转换。没有<algorithm>基于解决方案的解决方案。


[1]在2017年,德国拼字法理事会裁定可以正式使用“ẞ” U + 1E9E拉丁大写字母SHARP S,作为传统“ SS”转换旁边的一种选择,以避免歧义,例如在护照中(姓名大写) )。我美丽的例子,由于委员会的决定而过时了。


19
在一般情况下,这是正确的答案。该标准除了谎言和欺骗之外,没有提供处理“ ASCII”以外的任何内容的方法。它使您认为您也许可以处理UTF-16,但您不能。如此答案所言,如果不执行自己的unicode处理,就无法获得UTF-16字符串的正确字符长度(而不是字节长度)。如果必须处理真实文本,请使用ICU。谢谢@DevSolar
有限赎罪

默认情况下,ICU在Ubuntu / Windows上可用吗?还是需要单独安装?还有这个答案如何:stackoverflow.com/a/35075839/207661
Shital Shah

1
嘿,看,一个真实的答案!感谢您为我指明正确的方向,DevSolar。
Dan Bechard

2
@DevSolar同意!长度的概念在文本上是毫无意义的(我们可以在犯罪者列表中添加连字)。就是说,由于人们习惯于制表并控制占用一个长度单位的字符,因此代码点将是更直观的度量。哦,感谢给正确的答案,难过,看到这么远了:-(
masaers

3
@LF稍微好一点。但是很多事情仍然没有涉及:toupper并且tolower仍然可以在单个字符上工作。字符串类仍然没有归一化的概念(例如,“ü”被编码为“带有音符的u”还是“ u +组合音符”),或者字符串可以分隔或不分隔。清单继续。u8string(与其他标准字符串类一样)适合“通过”。但是,如果要处理 Unicode,则需要 ICU。
DevSolar

36

使用基于范围的C ++ 11的for循环,一个简单的代码将是:

#include <iostream>       // std::cout
#include <string>         // std::string
#include <locale>         // std::locale, std::tolower

int main ()
{
  std::locale loc;
  std::string str="Test String.\n";

 for(auto elem : str)
    std::cout << std::tolower(elem,loc);
}

9
但是,在法语计算机上,此程序不会转换法语允许的非ASCII字符。例如字符串'Test String123。ÉÏ\ n'将转换为:'test string123。ÉÏ\ n',但允许使用法语字符ÉÏ及其小写的couterpartsé和ï。该线程的其他消息似乎没有提供解决方案。
切开

我认为您需要为此设置适当的语言环境。
user1095108 2013年

@incises,然后有人发布了有关ICU的答案,这肯定是要走的路。比大多数其他尝试了解语言环境的解决方案更容易。
Alexis Wilke

我更希望个人尽可能不要使用外部库。
kayleeFrye_onDeck


15

这是Stefan Mai响应的后续操作:如果要将转换结果放在另一个字符串中,则需要在调用之前预先分配其存储空间std::transform。由于STL将转换后的字符存储在目标迭代器中(在循环的每次迭代中递增),因此目标字符串将不会自动调整大小,因此您可能会遭受内存重载。

#include <string>
#include <algorithm>
#include <iostream>

int main (int argc, char* argv[])
{
  std::string sourceString = "Abc";
  std::string destinationString;

  // Allocate the destination space
  destinationString.resize(sourceString.size());

  // Convert the source string to lower case
  // storing the result in destination string
  std::transform(sourceString.begin(),
                 sourceString.end(),
                 destinationString.begin(),
                 ::tolower);

  // Output the result of the conversion
  std::cout << sourceString
            << " -> "
            << destinationString
            << std::endl;
}

1
这并没有将Ä的大小调整为
ä– Purefan

也可以在此处使用后插入迭代器,而不是手动调整大小。
辣椒

11

使用基于范围的for循环和参考变量的另一种方法

string test = "Hello World";
for(auto& c : test)
{
   c = tolower(c);
}

cout<<test<<endl;

6

据我所知,Boost库在性能方面确实很差。我已经测试了他们对STL的unordered_map,它平均慢了3倍(最好的情况2,最糟糕的是10倍)。而且该算法看起来太低。

差异是如此之大,以至于我确信您将需要做的任何增加tolower使其等于“满足您的需求”的增加都比促进

我已经在Amazon EC2上进行了这些测试,因此在测试过程中性能会有所不同,但您仍然可以理解。

./test
Elapsed time: 12365milliseconds
Elapsed time: 1640milliseconds
./test
Elapsed time: 26978milliseconds
Elapsed time: 1646milliseconds
./test
Elapsed time: 6957milliseconds
Elapsed time: 1634milliseconds
./test
Elapsed time: 23177milliseconds
Elapsed time: 2421milliseconds
./test
Elapsed time: 17342milliseconds
Elapsed time: 14132milliseconds
./test
Elapsed time: 7355milliseconds
Elapsed time: 1645milliseconds

-O2 使它像这样:

./test
Elapsed time: 3769milliseconds
Elapsed time: 565milliseconds
./test
Elapsed time: 3815milliseconds
Elapsed time: 565milliseconds
./test
Elapsed time: 3643milliseconds
Elapsed time: 566milliseconds
./test
Elapsed time: 22018milliseconds
Elapsed time: 566milliseconds
./test
Elapsed time: 3845milliseconds
Elapsed time: 569milliseconds

资源:

string str;
bench.start();
for(long long i=0;i<1000000;i++)
{
    str="DSFZKMdskfdsjfsdfJDASFNSDJFXCKVdnjsafnjsdfjdnjasnJDNASFDJDSFSDNJjdsanjfsdnfjJNFSDJFSD";
    boost::algorithm::to_lower(str);
}
bench.end();

bench.start();
for(long long i=0;i<1000000;i++)
{
    str="DSFZKMdskfdsjfsdfJDASFNSDJFXCKVdnjsafnjsdfjdnjasnJDNASFDJDSFSDNJjdsanjfsdnfjJNFSDJFSD";
    for(unsigned short loop=0;loop < str.size();loop++)
    {
        str[loop]=tolower(str[loop]);
    }
}
bench.end();

我想我应该在专用计算机上进行测试,但是我将使用此EC2,因此我真的不需要在我的计算机上对其进行测试。


1
编译时是否打开了优化选项?我认为STL重载Boost库应该在较高的优化级别下更好地运行。
魏颂

1
我在其中一项测试中使用了-O2,仅此而已。
Etherealone

2
unordered_map的性能取决于哈希算法与您正在使用的数据的组合。没有一种适用于所有数据的魔术散列算法,以使unordered_map尽可能快。进行基准测试并尝试不同的方法。性能变差的原因是,由于使用的哈希值会导致大量冲突,这基本上会导致在列表中进行查找。请查看此站点以获取更多信息:fgda.pl/post/7/gcc-hash-map-vs-unordered-map 就我而言,链接处提供的功能减少了碰撞,因此非常快。
leetNightshade 2012年

6

将字符串转换为loweercase而不用担心std名称空间的最简单方法如下

1:带/不带空格的字符串

#include <algorithm>
#include <iostream>
#include <string>
using namespace std;
int main(){
    string str;
    getline(cin,str);
//------------function to convert string into lowercase---------------
    transform(str.begin(), str.end(), str.begin(), ::tolower);
//--------------------------------------------------------------------
    cout<<str;
    return 0;
}

2:字符串不带空格

#include <algorithm>
#include <iostream>
#include <string>
using namespace std;
int main(){
    string str;
    cin>>str;
//------------function to convert string into lowercase---------------
    transform(str.begin(), str.end(), str.begin(), ::tolower);
//--------------------------------------------------------------------
    cout<<str;
    return 0;
}

5

std::ctype::tolower()标准C ++本地化库中的代码将为您正确执行此操作。这是从下面的参考页中摘录的示例

#include <locale>
#include <iostream>

int main () {
  std::locale::global(std::locale("en_US.utf8"));
  std::wcout.imbue(std::locale());
  std::wcout << "In US English UTF-8 locale:\n";
  auto& f = std::use_facet<std::ctype<wchar_t>>(std::locale());
  std::wstring str = L"HELLo, wORLD!";
  std::wcout << "Lowercase form of the string '" << str << "' is ";
  f.tolower(&str[0], &str[0] + str.size());
  std::wcout << "'" << str << "'\n";
}

很好,只要您可以将字符转换到位即可。如果您的源字符串是const什么?这似乎使它更加混乱(例如,看起来您不能使用f.tolower()),因为您需要将字符放入新的字符串中。您会为运营商使用transform()诸如此类的东西std::bind1st( std::mem_fun() )吗?
quazar

对于const字符串,我们可以只创建一个本地副本,然后将其转换就位。
Sameer

是的,但是制作副本会增加更多的开销。
quazar

您可以将std :: transform与不带指针的ctype :: tolower版本一起使用。使用反向插入迭代器适配器,您甚至不必担心预先确定输出字符串的大小。
辣椒

很好,尤其是因为在libstdc ++的tolowerwith locale参数中,对的隐式调用use_facet似乎是性能瓶颈。我的一位同事通过boost::iequals用一个use_facet仅在循环外被调用一次的版本替换(存在此问题),就已经实现了100%的速度提高。
Arne Vogel's

3

Boost的替代方法是POCO(pocoproject.org)。

POCO提供两种变体:

  1. 第一个变体在不更改原始字符串的情况下进行复制。
  2. 第二个变体将原始字符串更改到位。
    “就地”版本的名称中始终带有“ InPlace”。

这两个版本如下所示:

#include "Poco/String.h"
using namespace Poco;

std::string hello("Stack Overflow!");

// Copies "STACK OVERFLOW!" into 'newString' without altering 'hello.'
std::string newString(toUpper(hello));

// Changes newString in-place to read "stack overflow!"
toLowerInPlace(newString);

3

有一种方法可以将大写转换为小写而不用执行if tests,这很简单。isupper()函数/宏对clocale.h的使用应解决与您的位置有关的问题,但是如果没有,您可以随时调整UtoL []以适应您的内心需求。

假设C的字符实际上只是8位整数(暂时忽略宽字符集),则可以创建一个256字节的数组,其中包含另一组字符,然后在转换函数中将字符串中的字符用作下标到转换数组。

但是,可以使用大写数组成员BYTE int值代替小写字符,而不是1对1映射。您可能会在这里发现islower()和isupper()有用。

在此处输入图片说明

代码看起来像这样...

#include <clocale>
static char UtoL[256];
// ----------------------------------------------------------------------------
void InitUtoLMap()  {
    for (int i = 0; i < sizeof(UtoL); i++)  {
        if (isupper(i)) {
            UtoL[i] = (char)(i + 32);
        }   else    {
            UtoL[i] = i;
        }
    }
}
// ----------------------------------------------------------------------------
char *LowerStr(char *szMyStr) {
    char *p = szMyStr;
    // do conversion in-place so as not to require a destination buffer
    while (*p) {        // szMyStr must be null-terminated
        *p = UtoL[*p];  
        p++;
    }
    return szMyStr;
}
// ----------------------------------------------------------------------------
int main() {
    time_t start;
    char *Lowered, Upper[128];
    InitUtoLMap();
    strcpy(Upper, "Every GOOD boy does FINE!");

    Lowered = LowerStr(Upper);
    return 0;
}

同时,这种方法将允许您重新映射要更改的任何其他字符。

这种方法在现代处理器上运行时具有一个巨大的优势,因为没有测试包含分支,因此无需进行分支预测。这样可以将CPU的分支预测逻辑保存为其他循环,并可以防止流水线停顿。

这里的一些人可能会认识到这种方法与用于将EBCDIC转换为ASCII的方法相同。


2
“有没有一种方法可以将大写转换为小写而不用做测试”,听说过查询表吗?
的Gabor Buella

1
否定字符的不确定行为。
罗兰·伊利格

现代CPU瓶颈是内存而不是CPU。基准测试将很有趣。
Contango

3

由于没有一个答案中提到的即将到来的范围库,这是因为在C ++ 20的标准库,目前可单独购买GitHub上range-v3,我想补充用它来执行此转换的方式。

要就地修改字符串:

str |= action::transform([](unsigned char c){ return std::tolower(c); });

生成新字符串:

auto new_string = original_string
    | view::transform([](unsigned char c){ return std::tolower(c); });

(不要忘了#include <cctype>和必需的Ranges标头。)

注意:使用unsigned charlambda作为参数是受cppreference启发的,它指出:

与from中的所有其他函数一样<cctype>std::tolower如果参数的值既不能表示unsigned char也不等于,则的行为是不确定的EOF。为了安全地将这些函数与Plain chars(或signed chars)一起使用,应首先将参数转换为unsigned char

char my_tolower(char ch)
{
    return static_cast<char>(std::tolower(static_cast<unsigned char>(ch)));
}

同样,当迭代器的值类型为char或时,则不应将它们直接与标准算法一起使用signed char。而是将值转换为unsigned charfirst:

std::string str_tolower(std::string s) {
    std::transform(s.begin(), s.end(), s.begin(), 
                // static_cast<int(*)(int)>(std::tolower)         // wrong
                // [](int c){ return std::tolower(c); }           // wrong
                // [](char c){ return std::tolower(c); }          // wrong
                   [](unsigned char c){ return std::tolower(c); } // correct
                  );
    return s;
}

3

我自己的模板函数执行大写/小写。

#include <string>
#include <algorithm>

//
//  Lowercases string
//
template <typename T>
std::basic_string<T> lowercase(const std::basic_string<T>& s)
{
    std::basic_string<T> s2 = s;
    std::transform(s2.begin(), s2.end(), s2.begin(), tolower);
    return std::move(s2);
}

//
// Uppercases string
//
template <typename T>
std::basic_string<T> uppercase(const std::basic_string<T>& s)
{
    std::basic_string<T> s2 = s;
    std::transform(s2.begin(), s2.end(), s2.begin(), toupper);
    return std::move(s2);
}

这就是我所需要的。我只是使用towlower支持UTF-16的宽字符。
7

2

如果您想简单一些,可以使用以下宏技术:

#define STRTOLOWER(x) std::transform (x.begin(), x.end(), x.begin(), ::tolower)
#define STRTOUPPER(x) std::transform (x.begin(), x.end(), x.begin(), ::toupper)
#define STRTOUCFIRST(x) std::transform (x.begin(), x.begin()+1, x.begin(),  ::toupper); std::transform (x.begin()+1, x.end(),   x.begin()+1,::tolower)

但是,请注意,@ AndreasSpindler对这个答案的评论仍然是一个重要的考虑因素,但是,如果您正在处理的不只是ASCII字符。


1
我不赞成在存在完美解决方案时提供宏-您甚至可以提供这些解决方案。
清晰的时间是

2
宏技术意味着对于通常在编程中会经常使用的某些东西,较少的代码键入。为什么不使用它?否则,为什么还要有宏呢?
Volomike '17

3
宏是C遗留下来的东西,正在努力摆脱它。如果要减少输入量,请使用函数或lambda。void strtoupper(std::string& x) { std::transform (x.begin(), x.end(), x.begin(), ::toupper); }
清晰的时间为

1
@Clearer因为我想成为一个更好的编码人员,能否为我提供任何ANSI doc链接,其中任何ANSI C ++委员会都说:“我们需要召开会议以摆脱C ++的宏”?还是其他路线图?
Volomike

2
不,我不能。不过,在很多场合下,巴涅(Bjarne)对这个话题的立场已经很明确了。此外,还有很多理由不使用C以及C ++中的宏。x可能是一个有效的表达式,恰好可以正确编译,但是由于宏的原因,将给出完全虚假的结果。
清晰的时间为

2
// tolower example (C++)
#include <iostream>       // std::cout
#include <string>         // std::string
#include <locale>         // std::locale, std::tolower

int main ()
{
  std::locale loc;
  std::string str="Test String.\n";
  for (std::string::size_type i=0; i<str.length(); ++i)
    std::cout << std::tolower(str[i],loc);
  return 0;
}

有关更多信息:http : //www.cplusplus.com/reference/locale/tolower/


2

有没有一种替代方法可以100%地起作用?

没有

在选择降低装箱方法之前,您需要问自己几个问题。

  1. 字符串如何编码?纯ASCII码?UTF-8?某种形式的扩展ASCII传统编码?
  2. 小写到底是什么意思?案例映射规则因语言而异!您是否需要本地化到用户语言环境的内容?您是否希望在您的软件运行的所有系统上都能表现出一致的性能?您是否只想小写ASCII字符并通过其他所有内容?
  3. 有哪些可用的库?

回答完这些问题后,您就可以开始寻找适合您需求的解决方案。没有一种尺寸适合所有地方的所有人!


2

试试这个功能:)

string toLowerCase(string str) {
    int str_len = str.length();
    string final_str = "";
    for(int i=0; i<str_len; i++) {
        char character = str[i];
        if(character>=65 && character<=92) {
            final_str += (character+32);
        } else {
            final_str += character;
        }
    }
    return final_str;
}

1

在Microsoft平台上,您可以使用以下strlwr功能族:http : //msdn.microsoft.com/zh-cn/library/hkxwh33z.aspx

// crt_strlwr.c
// compile with: /W3
// This program uses _strlwr and _strupr to create
// uppercase and lowercase copies of a mixed-case string.
#include <string.h>
#include <stdio.h>

int main( void )
{
   char string[100] = "The String to End All Strings!";
   char * copy1 = _strdup( string ); // make two copies
   char * copy2 = _strdup( string );

   _strlwr( copy1 ); // C4996
   _strupr( copy2 ); // C4996

   printf( "Mixed: %s\n", string );
   printf( "Lower: %s\n", copy1 );
   printf( "Upper: %s\n", copy2 );

   free( copy1 );
   free( copy2 );
}

0

代码段

#include<bits/stdc++.h>
using namespace std;


int main ()
{
    ios::sync_with_stdio(false);

    string str="String Convert\n";

    for(int i=0; i<str.size(); i++)
    {
      str[i] = tolower(str[i]);
    }
    cout<<str<<endl;

    return 0;
}


0

复制是因为不允许改善答案。非常感谢


string test = "Hello World";
for(auto& c : test)
{
   c = tolower(c);
}

说明:

for(auto& c : test)是基于范围的for循环类型:
for (range_declaration:range_expression)loop_statement

  1. range_declarationauto& c
    这里的自动说明符用于自动类型推导。因此,从变量初始值设定项中推导出类型。

  2. range_expressiontest
    在这种情况下,范围是string的字符test

字符串的字符test可用作for循环标识符中的参考c


请说明您从何处复制答案。
bfontaine

0

C ++没有为字符串实现tolower或toupper方法,但是可用于char。可以轻松读取字符串的每个字符,将其转换为所需的大小写,然后将其放回字符串中。不使用任何第三方库的示例代码:

#include<iostream>

int main(){
  std::string str = std::string("How IS The Josh");
  for(char &ch : str){
    ch = std::tolower(ch);
  }
  std::cout<<str<<std::endl;
  return 0;
}

对于基于字符的字符串操作:对于字符串中的每个字符


-1

这可能是将大写转换为小写,反之亦然的另一个简单版本。我使用VS2017社区版本来编译此源代码。

#include <iostream>
#include <string>
using namespace std;

int main()
{
    std::string _input = "lowercasetouppercase";
#if 0
    // My idea is to use the ascii value to convert
    char upperA = 'A';
    char lowerA = 'a';

    cout << (int)upperA << endl; // ASCII value of 'A' -> 65
    cout << (int)lowerA << endl; // ASCII value of 'a' -> 97
    // 97-65 = 32; // Difference of ASCII value of upper and lower a
#endif // 0

    cout << "Input String = " << _input.c_str() << endl;
    for (int i = 0; i < _input.length(); ++i)
    {
        _input[i] -= 32; // To convert lower to upper
#if 0
        _input[i] += 32; // To convert upper to lower
#endif // 0
    }
    cout << "Output String = " << _input.c_str() << endl;

    return 0;
}

注意:如果有特殊字符,则需要使用条件检查进行处理。


-8

我尝试了std :: transform,我得到的是可恶的stl抄写错误,只有200年前的德鲁伊才能理解(无法转换为flibidi flabidi flu)

这工作正常,可以很容易地进行调整

string LowerCase(string s)
{
    int dif='a'-'A';
    for(int i=0;i<s.length();i++)
    {
        if((s[i]>='A')&&(s[i]<='Z'))
            s[i]+=dif;
    }
   return s;
}

string UpperCase(string s)
{
   int dif='a'-'A';
    for(int i=0;i<s.length();i++)
    {
        if((s[i]>='a')&&(s[i]<='z'))
            s[i]-=dif;
    }
   return s;
}
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.