大文字 - c++ 小文字 判定




どのようにstd:: stringを小文字に変換するのですか? (14)

std::stringを小文字に変換したい。 私は関数tolower()認識していますが、これまではこの関数に問題がありましたが、とにかくstd::string使用には各文字の繰り返しが必要になるため理想的ではありません。

100%時間がかかる代替手段はありますか?


コードスニペット

#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;
}

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);
}


stdネームスペースを気にせずに文字列をloweercaseに変換する最も簡単な方法は次のとおりです

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;
}

答えを改善することができなかったのでコピーする。 ありがとうございます

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
    この場合の範囲は文字列testの文字です。

文字列testの文字は、識別子c介してforループ内の参照として使用できます。


tl; dr

ICUライブラリを使用します

まず、あなたは質問に答える必要がありますstd::stringあなたのstd::string エンコーディングは何ですか? ISO-8859-1ですか? あるいはISO-8859-8ですか? またはWindowsのコードページ1252? あなたはそれを知っている大文字から小文字に変換するために使用しているものは何ですか? (または、 0x7f超える文字は悲惨に失敗し0x7fか?)

コンテナとしてstd::stringを使用するUTF-8(8ビットエンコーディングの中で唯一の選択肢)を使用している場合、マルチバイト文字を格納しているので、あなたはまだ物事をコントロールしていると信じているでしょうマルチバイトの概念を認識していないコンテナ内のシーケンス。 .substr()ような単純なものでさえも、時間を刻んでいます。 (マルチバイトシーケンスを分割すると、無効な(サブ)文字列が返されるため)

そして、あなたがstd::toupper( 'ß' )ようなものを試すとすぐに、 どんなエンコーディングで 、あなたは深刻な問題に陥っています。 (ここで必要な"SS"ではなく、 1つの結果キャラクタしか提供できない標準ライブラリでこの「正しい」ことができないため)[1]もう1つの例はstd::tolower( 'I' ) ロケールによって異なる結果が得られるはずです 。 ドイツでは、 'i'は正しいでしょう。 トルコでは、 'ı' (ラテン小文字のドットレスI)が期待される結果です。

次に、標準ライブラリは、ソフトウェアが動作しているマシンでどのロケールがサポートされているかによって異なります。そうでない場合はどうしますか?

だからあなたが本当に探しているのは、これを正しく扱うことができる文字列クラスです。これ std::stringではありません

(C ++ 11のノート: std::u16stringstd::u32string優れていますが、まだ完全ではありません。)

Boost 素晴らしいAPIですが、Boost.Localeは基本的にICUのラッパーです。 BoostがICUサポートでコンパイルされていない場合、Boost.Localeは標準ライブラリ用にコンパイルされたロケールサポートに限定されます。

そして、私を信じて、ブーストをICUでコンパイルすることは時々本当の痛みになるかもしれません。 (Windows用のコンパイル済みのバイナリはないので、アプリケーションと一緒にそれらを提供しなければならず、それはワームの全く新しい缶開く...)

個人的には、馬の口から直接完全なUnicodeサポートを取得し、 ICUライブラリを直接使用することをおすすめします。

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

#include <iostream>

int main()
{
    char const * someString = "Eidenges\xe4\xdf";
    icu::UnicodeString someUString( someString, "ISO-8859-1" );
    // Setting the locale explicitly here for completeness.
    // Usually you would use the user-specified system locale.
    std::cout << someUString.toLower( "de_DE" ) << "\n";
    std::cout << someUString.toUpper( "de_DE" ) << "\n";
    return 0;
}

コンパイル(この例ではG ++):

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

これは与える:

eidengesäß
EIDENGESÄSS

[1] 2017年、ドイツのOrthography評議会は「U + 1E9E LATIN CAPITAL LETTER SHARP S」を、パスポートなどの曖昧さを避けるための伝統的な「SS」変換以外のオプションとして正式に使用することができると裁定した)。 委員会の決定で廃止されました。


このための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);

これから:

#include <algorithm>
#include <string> 

std::string data = "Abc"; 
std::transform(data.begin(), data.end(), data.begin(), ::tolower);

あなたは本当に各キャラクターを反復することで逃げるつもりはありません。 文字が小文字か大文字かを知る方法はありません。

あなたが本当にtolower()嫌っているのであれば、あなたが使用することをお勧めしない、移植性のない方法があります:

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

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

::tolower()は、特にUTF-8のようなマルチバイトエンコーディングを使用している場合には、多くのスクリプトには::tolower()ません。


これは、大文字を小文字に変換するもう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;
}

注:特殊文字がある場合は、条件チェックを使用して処理する必要があります。


単純なものを望むなら、マクロテクニックがあります:

#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文字以外のものに取り組んでいる場合でも重要な考慮事項です。



標準C ++ローカリゼーションライブラリのstd::ctype::tolower()はこれを正しく行います。 これは、下の参照ページから抽出された例です

#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";
}

私はstd :: transformを試してみましたが、200年前のdruidsだけが理解できる(sta cripticのコンパイルエラーです)(flibidi flabidiからfluibidiに変換できません)

これはうまく動作し、簡単に微調整できます

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;
}

// 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/





tolower