0

コマンドラインから入力を取り、それを小文字に変換しようとしています。これを行うために、私は書いた:

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 ループの 2 回目の反復で失敗します (より正確には、 で失敗しますnsrank[i] = tolower(srank[i]);)。表示されるエラーは「文字列の部分文字列が範囲外です」ですが、文字列にはまだ文字が残っているため、これがどのように発生するのかわかりません。

例を挙げると、「Ace of Spades」と入力すると、最初 (i=0 のとき) まで繰り返され、「a」罰金が転送されます。ただし、その後、i が 1 に等しい (これは「c」を参照する必要があります) で戻りますが、代わりに、部分文字列が範囲外であることを通知します (への代入は正常にchar temp機能します)。デバッグ中、「nsrank」は 15 のサイズを要求するので、それがどのように範囲外になるかわかりません....

4

2 に答える 2

2

問題は、nsrank が空文字列なので、operator[]でアクセスする....

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);
于 2014-04-11T07:13:32.007 に答える