C'de bir dizeyi nasıl küçük harfle yazabilirim?


108

Karışık harfli bir dizeyi C'deki küçük harfli bir dizeye nasıl dönüştürebilirim?


2
ASCII ile sadece az harfleriyle mi uğraşıyorsunuz?
Mark Byers

1
ascii. bunu nasıl hesaba katarım? Aşağıdaki örnek yine de işe yarar mı? karakterim bir '#' ise ve üzerinde tolower () çağrılırsa ne olur?
Tony Stark

1
İşe yarayacak. Dizinizde é veya Ü gibi şeyler olup olmadığını düşünüyordum.
Mark Byers

1
Neden sadece "strlwr" kullanmıyorsunuz? strlwr((char*)str);Sadece dizenin içinden geçer ve kendisini dönüştürür.
Larry 18

1
@Larry Bu standart değil.
ortası

Yanıtlar:


154

Standart kitaplıkta ve bu, böyle bir işlevi gerçekleştirmenin görebildiğim en basit yolu. Yani evet, sadece dizede döngü yapın ve her karakteri küçük harfe çevirin.

Bunun gibi önemsiz bir şey:

#include <ctype.h>

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

veya bir astar tercih ediyorsanız, bunu JF Sebastian tarafından kullanabilirsiniz:

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

35
for ( ; *p; ++p) *p = tolower(*p);daha deyimsel görünüyor.
jfs

14
@JF oraya gidiyorsun. Onlar korkutucu ya da güzel :) bakmak kod isterseniz bağlıdır (çok okunabilir bir astar, ancak göz korkutucu yapar)
Earlz

bu bana eğer str bir ise segfault verir char *, ancak str bir char dizisi değilse değil. Bunun için herhangi bir açıklaman var mı?
Electric Coffee

1
Tek satırlık ipin işaretçinizi kaybetmenize neden olacağına inanıyorum.
Ace C

2
Bir astarın anlatılmamış sonuçları olacağına inanıyorum.
NOP da CALL

7

küçük harfe dönüştürmek, kendinizi ASCII ile sınırlarsanız, yükselen bit 0x60 ile eşdeğerdir:

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

6
Onu biraz daha okunaklı hale getirmek için yapabilirsinizfor(char *p = pstr;*p;++p) *p=*p>='A'&&*p<='Z'?*p|0x60:*p;
Grant Peters

7
Bu sürüm aslında glibc'den daha yavaştır tolower(). Makinemde 55.2'ye karşı 44.15.
jfs

tolower () karakterlerle ilgilenir; sadece makro ise
Oleg Razgulyaev

1
@oraz: tolower () imzalıdır int (*)(int). İşte performans ölçümleri için kullanılan kod gist.github.com/370497
jfs

@JF: Görüyorum, tabloyu kullanmışlar, ancak optimize edebilirim: for (; * p; ++ p) if (* p> 'Z') {devam;} else if (* p <'A') {devam;} else {* p = * p | 0x60;}
Oleg Razgulyaev

1

Yalnızca ASCII dizeleriyle mi uğraşıyorsunuz ve yerel ayar sorunlarınız yok mu? O zaman evet, bunu yapmanın iyi bir yolu olur.


tolower () ascii az olmayan bir karakterde çağrılırsa ne olur? sevmek '!' veya "#". '#' üzerinde test ettim ve iyi çalışıyor gibiydi. bu genellikle az harfleri olmayan tüm ascii karakterleri için geçerli midir?
Tony Stark

1
@hatorade: tolower()'A' .. 'Z' aralığında değilse bağımsız değişkeni değiştirmeden bırakır.
jfs

1
! ve # her ikisi de ascii karakteridir. Mark, karakter başına bir bayt olduğunu
varsayamayacağınız


1

Kullanmak kadar özensiz davranacaksak, şunu yapın tolower():

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

Ancak, onu bazı semboller / rakamlarla beslerseniz patlar ve genel olarak kötüdür. Yine de iyi röportaj sorusu.


6
Evet, bu çeşitli sembolleri katlar / döndürür / parçalayacaktır (ASCII'de, herhangi bir sembol, kontrol karakteri veya bit 5 açık olan sayı, bit 5 setiyle aynı karakter kodu haline gelecektir, vb.) onu kullanın.
Ken S

Bu gönderi meta üzerinde tartışılıyor .
Patrick Hofman

1

Daha iyi performans elde etmek için işaretçiyi döngüye alma:

#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;
}
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.