将字符串转换为小写时,子字符串超出范围

Substring out of range when converting string to lowercase

本文关键字:字符串 范围 转换      更新时间:2023-10-16

我正试图从命令行获取输入,然后将其转换为小写。为了做到这一点,我写了:

istream& operator>>(istream& is, Card& c)
{
    static map<string,Card::Rank> mr = createmr();
    static map<string,Card::Suit> ms = createms();
    string srank, c1, ssuit;
    if (is >> srank >> c1 >> ssuit)
    {
        if (c1 == "of")
        {
            string nsrank;
            string nssuit;
            for(unsigned int i = 0; i < srank.length(); i++) {
                char temp = srank[i];
                nsrank[i] = tolower(srank[i]);
            }

它在for循环的第二次迭代中失败(更准确地说,它在nsrank[i] = tolower(srank[i]);上失败)。显示的错误是"字符串子字符串超出范围",但我不明白为什么会出现这种情况,因为字符串中肯定还有字符。

举个例子:如果我输入"黑桃王牌",那么它将遍历第一次(当I=0时)并传递"a"罚款。然而,它返回到i等于1(应该指的是"c"),但它却"告诉"我子字符串超出了范围(即使对char temp的赋值工作正常)。在调试过程中,"nsrank"声称大小为15,所以我看不出这怎么可能超出范围。。。。

问题是nsrank是一个空字符串,因此使用运算符[]进行访问。。。。

如果pos不大于字符串长度,则函数永远不会抛出异常(没有抛出保证)。否则,会导致未定义行为

这个对我很有效:http://ideone.com/3LcYqv

#include <iostream>
using namespace std;
int main() {
    string srank="Ace of Spades";
    string nsrank;
    nsrank.resize(srank.length());
            for(unsigned int i = 0; i < srank.length(); i++) {
                char temp = srank[i];
                nsrank[i] = tolower(srank[i]);
            }
    cout << nsrank << endl;
    return 0;
}

关键是调整大小以使nsrank与srank大小相同。

编辑:添加了紧凑型解决方案

来自许多地方,其中来自这个答案

#include <algorithm>
#include <string>
string srank="Ace of Spades";
string nsrank=srank;
std::transform(nsrank.begin(), nsrank.end(),nsrank.begin(), ::toupper);

在进入循环之前调整nsrank大小以匹配srank的大小