6

次のコードがあるとします。

 void parseInput(fstream &inputFile) {
        const int LENGTH = 81;
        char line[LENGTH];

        while(!inputFile.fail()) {
            inputFile.getline(line,LENGTH);
            line = tolower(line);
            cout << line << endl;
        }
    }

コンパイルすると、次のエラーが発生します。

エラー E2285 : 関数 parseInput(fstream &) で 'tolower(char *)' に一致するものが見つかりませんでした

int []ではなくintを返すことはわかっていますが、getlineを使用する代わりに、入力文字を文字ごとに取得する必要があるということですか? ライン全体を低く変換する方法はありますか? みんなの助けを前もってありがとう!

4

6 に答える 6

6

Hi tolower 関数の入力パラメータは char* ではなく char でなければなりませんが、std を使用する場合は、string と std:transform を使用して文字列を小文字にすることができます

std::string data = “MyStrData”; 
std::transform(data.begin(), data.end(), data.begin(), ::tolower);
于 2010-12-05T22:15:05.003 に答える
3

スタンドアロンtolower関数は 1 つだけを受け入れint、 はint厳密に非負または である必要がありますEOF。それ以外の場合の動作は未定義です。の別のバージョンがtolower存在しますが、これはテンプレートです。これらの事実は両方とも、それらをtransform簡単かつ安全に使用することを困難にします.

C++ は、ここで使用できるファセットも提供tolowerします。ctype

std::ctype<char> const& c = std::use_facet< std::ctype<char> >(std::locale());
c.tolower(line, line + std::strlen(line));

しかし、コード全体を見ると、あなたは配列とポイントに慣れていないことがわかります。そのためstd::string、使いやすいアルゴリズムを使い始める必要があるのではないでしょうか? boost::string_algoケース変換を調べてください。

于 2010-12-05T22:23:13.023 に答える
1

うーん、ここでの3つの答えはtolower 間違って使用することができました。

その引数は、非負または特別なEOF値である必要があります。そうでない場合、未定義動作です。持っているのがASCII文字だけの場合、コードはすべて負ではないため、その特殊なケースでは、直接使用できます。ただし、ノルウェー語の「blåbærsyltetøy」(ブルーベリージャム)のようにASCII以外の文字がある場合、それらのコードはおそらく負であるため、引数をunsignedtypeにキャストするchar必要があります。

また、この場合、Cロケールを関連するロケールに設定する必要があります。

たとえば、ユーザーのデフォルトロケールに設定できます。これは、の引数として空の文字列で示されますsetlocale

例:

#include <iostream>
#include <string>           // std::string
#include <ctype.h>          // ::tolower
#include <locale.h>         // ::setlocale
#include <stddef.h>         // ::ptrdiff_t

typedef unsigned char   UChar;
typedef ptrdiff_t       Size;
typedef Size            Index;

char toLowerCase( char c )
{
    return char( ::tolower( UChar( c ) ) );     // Cast to unsigned important.
}

std::string toLowerCase( std::string const& s )
{
    using namespace std;
    Size const      n   = s.length();
    std::string     result( n, '\0' );

    for( Index i = 0;  i < n;  ++i )
    {
        result[i] = toLowerCase( s[i] );
    }
    return result;
}

int main()
{
    using namespace std;
    setlocale( LC_ALL, "" );                    // Setting locale important.
    cout << toLowerCase( "SARAH CONNER LIKES BLÅBÆRSYLTETØY" ) << endl;
}

代わりにstd::transform:を使用してこれを行う例

#include <iostream>
#include <algorithm>        // std::transform
#include <functional>       // std::ptr_fun
#include <string>           // std::string
#include <ctype.h>          // ::tolower
#include <locale.h>         // ::setlocale
#include <stddef.h>         // ::ptrdiff_t

typedef unsigned char   UChar;

char toLowerCase( char c )
{
    return char( ::tolower( UChar( c ) ) );     // Cast to unsigned important.
}

std::string toLowerCase( std::string const& s )
{
    using namespace std;
    string          result( s.length(), '\0' );

    transform( s.begin(), s.end(), result.begin(), ptr_fun<char>( toLowerCase ) );
    return result;
}

int main()
{
    using namespace std;
    setlocale( LC_ALL, "" );                    // Setting locale important.
    cout << toLowerCase( "SARAH CONNER LIKES BLÅBÆRSYLTETØY" ) << endl;
}

Cロケールの代わりにC++レベルのロケールのものを使用する例については、Johannesの回答を参照してください。

乾杯&hth。、

于 2010-12-05T23:24:19.843 に答える
0

はいといいえ。行全体を取得できますが、forループを使用してcharごとに(およびtolowerを使用して)印刷します。

于 2010-12-05T22:19:10.777 に答える
0

次のループを実行するだけで、文字列を 1 文字ずつ小文字に変換できます。

const int lineLen = strlen( line );
for ( int i = 0; i < lineLen; i++ )
{
     line[i] = static_cast< char >( ::tolower( static_cast< unsigned char >( line[i] ) ) );
}

編集:さらに、次のコードはさらに簡単です(文字列がnullで終了していると仮定します)。

_strlwr( line );
于 2010-12-05T22:15:17.850 に答える
-1

tolower()一度に 1 つのキャラクターだけを操作します。次のようなことをする必要があります

for(int i = 0; i < LENGTH; ++i)
  line[i] = tolower(line[i]);
于 2010-12-05T22:15:40.590 に答える