Cで文字列を小文字にするにはどうすればよいですか?


108

Cで大文字と小文字が混在する文字列を小文字の文字列に変換するにはどうすればよいですか?


2
あなたは単に文字aからzのASCIIを扱っていますか?
Mark Byers、2010

1
アスキー。それをどのように考慮しますか?以下の例はまだ機能しますか?charが「#」で、tolower()が呼び出された場合はどうなりますか?
トニースターク

1
うまくいきます。文字列にéやÜなどが含まれているかどうかをもっと考えていました。
マーク・バイアーズ2010

1
なぜ「strlwr」を使用しないのですか?strlwr((char*)str);それは単に文字列を通過し、それ自体を変換します。
ラリー

@ラリーそれは非標準です。
半ば

回答:


152

それは標準ライブラリにあり、それは私がそのような関数を実装するために見ることができる最も簡単な方法です。したがって、はい、文字列をループして、各文字を小文字に変換します。

このような些細なこと:

#include <ctype.h>

for(int i = 0; str[i]; i++){
  str[i] = tolower(str[i]);
}

または、1つのライナーを使用する場合は、JFセバスチャンのライナーを使用できます。

for ( ; *p; ++p) *p = tolower(*p);

35
for ( ; *p; ++p) *p = tolower(*p);より慣用的なようです。
jfs

14
@JF、そこに行きます。彼らがコードを恐ろしいか素敵に見せたいかどうかに依存します:)(非常に読みやすい1つのライナーですが、恐ろしく見えます)
Earlz

strがの場合、これによりsegfaultが得られますが、char *strがchar配列の場合は得られません。その説明はありますか?
Electric Coffee

1
ライナーが1つあると、ストリングへのポインターが失われると思います。
Ace.C 2017

2
私は、1つのライナーには、計り知れない影響があると信じています。
NOP da CALL

7

小文字に変換することは、ASCIIに制限する場合、立ち上がりビット0x60と同じです。

for(char *p = pstr; *p; ++p)
    *p = *p > 0x40 && *p < 0x5b ? *p | 0x60 : *p;

5
少し読みやすくするには、次のようにしますfor(char *p = pstr;*p;++p) *p=*p>='A'&&*p<='Z'?*p|0x60:*p;
Grant Peters

7
このバージョンは実際にはglibcのバージョンよりも低速ですtolower()。私のマシンでは55.2対44.15。
jfs 2010

想像できません。tolower()は文字を扱います。マクロの場合のみ
Oleg Razgulyaev 2010

1
@oraz:tolower()にはint (*)(int)署名があります。これは、パフォーマンス測定に使用されるコードですgist.github.com/370497
jfs

@JF:わかりました、テーブルを使用しましたが、最適化できます:for(; * p; ++ p)if(* p> 'Z'){continue;} else if(* p <'A') {continue;} else {* p = * p | 0x60;}
Oleg Razgulyaev 2010

1

あなたはASCII文字列を扱っているだけで、ロケールの問題はありませんか?それなら、そうするのが良い方法でしょう。


ASCII以外のaz charでtolower()が呼び出されるとどうなりますか?お気に入り '!' または「#」。'#'でテストしましたが、問題なく動作するようです。これは一般にa〜zの文字ではないすべてのASCII文字に当てはまりますか?
トニースターク

1
@hatorade:tolower()'A' .. 'Z'の範囲にない場合、引数は変更されません。
jfs 2010

1
!と#はどちらもASCII文字です。Markは、UTF8のような他のエンコーディングを参照していましたが、(このソリューションのように)文字ごとに1バイトがあるとは想定できません
hdgarrood


1

を使うのと同じくらいだらしない場合はtolower()、次のようにします。

char blah[] = "blah blah Blah BLAH blAH\0"; int i=0; while(blah[i]|=' ', blah[++i]) {}

しかし、まあ、あなたがそれにいくつかのシンボル/数字を与えると、それはちょっと爆発します、そして一般的にそれは悪です。いい面接の質問ですが。


6
ええ、これはさまざまな記号を折りたたみ/スピンドル/切断します(ASCIIでは、ビット5がクリアされた記号、制御文字、または数字はビット5が設定された同じ文字コードになります)。これを使って。
Ken S

この投稿はmetaで議論されています。
Patrick Hofman、2014

0

ポインターをループしてパフォーマンスを向上させる:

#include <ctype.h>

char* toLower(char* s) {
  for(char *p=s; *p; p++) *p=tolower(*p);
  return s;
}
char* toUpper(char* s) {
  for(char *p=s; *p; p++) *p=toupper(*p);
  return s;
}
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.