2010-04-18 12 views
69

Jaki jest najlepszy/najczystszy sposób na przekonwertowanie złożonego ciągu znaków na małe litery w C?c - przekonwertuj ciąg z wieloma literami na wszystkie małe litery:

+2

Czy zajmujesz się tylko ASCII literami a-z? –

+0

ascii. jak bym to wziął pod uwagę? czy poniższy przykład nadal działa? co się stanie, jeśli mój znak jest "#" i zostanie wywołany tolower()? – sepiroth

+1

To zadziała. Byłem bardziej myślenia, jeśli twój ciąg zawiera rzeczy takie jak é lub Ü. –

Odpowiedz

111

Jest w standardowej bibliotece i jest to najprostszy sposób, jaki mogę zobaczyć, aby zaimplementować taką funkcję. Więc tak, po prostu przeprowadź pętlę przez łańcuch i zamień każdy znak na małe litery.

Coś trywialne tak:

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

lub jeśli wolisz jeden wkładki, można użyć tego jednego JF Sebastian:

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

'for (; * p; ++ p) * p = tolower (* p);' wydaje się bardziej idiomatyczny. – jfs

+13

@ J.F. proszę bardzo. Zależy od tego, czy kod ma wyglądać przerażająco, czy ładnie :) (bardzo czytelny jeden liniowiec, ale wygląda na przerażający) – Earlz

+0

daje mi to segfault, jeśli str jest "char *", ale nie jeśli str jest tablicą char. Masz jakieś wytłumaczenie? –

2

Czy zajmujesz się tylko ciągami ASCII i nie masz problemów z ustawieniami regionalnymi? Więc tak, to byłby dobry sposób na zrobienie tego.

+0

co się dzieje, gdy wywoływana jest funkcja tolower() w char-a-z-ascii? lubić '!' lub "#". testowałem go na "#" i wydawało się, że działa dobrze. czy jest to na ogół prawdziwe dla wszystkich znaków ASCII, które nie są literami a-z? – sepiroth

+1

@hatorade: 'tolower()' pozostawia argument niezmieniony, jeśli nie znajduje się w zakresie "A" .. "Z". – jfs

+1

! i # to oba znaki ascii. Mark odwoływał się do innych kodowań, takich jak UTF8, gdzie nie można założyć, że istnieje jeden bajt na znak (jak to robi) – hdgarrood

6

do konwersji na małe litery jest równoważna rosnąć nieco 0x60:

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

(łacińskiego kodowej oczywiście)

+3

Aby było to nieco bardziej czytelne, możesz zrobić "dla (char * p = pstr; * p; ++ p) * p = * p> = 'A' && * p <= 'Z'? * P | 0x60: * p; ' –

+4

Ta wersja jest wolniejsza od' tolower() 'w glibc. 55,2 vs. 44,15 na moim komputerze. – jfs

+0

Nie mogę sobie wyobrazić, że: tolower() zajmuje się znakami; tylko jeśli jest to makro –

1

Jeśli mamy zamiar być tak niechlujny jak używać tolower(), to zrobić:

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

Ale dobrze , wybucha, jeśli nakarmisz go symbolami/cyframi, a ogólnie jest zły. Ale dobre pytanie z wywiadu.

+5

Tak, to spowoduje złożenie/wrzeciono/okaleczenie różnych symboli (w ASCII każdy symbol, znak kontrolny lub cyfra z bitem 5 clear stanie się tym samym kodem znaku z ustawieniem bitu 5 itd.) Tak naprawdę, poważnie, don ' t go używaj. –

+0

Ten post jest omówiony na [meta] (http://meta.stackoverflow.com/questions/270402/is-ghetto-an-offensiveword). –

Powiązane problemy