C에서 문자열을 어떻게 소문자로 지정합니까?


108

C에서 대소 문자 혼합 문자열을 소문자 문자열로 어떻게 변환 할 수 있습니까?


2
az 문자로만 ASCII를 처리하고 있습니까?
Mark Byers

1
ascii. 그것을 어떻게 고려할까요? 아래 예가 여전히 작동합니까? 내 문자가 '#'이고 tolower ()가 호출되면 어떻게됩니까?
Tony Stark

1
작동합니다. 나는 당신의 문자열에 é 또는 Ü와 같은 것이 포함되어 있는지 더 많이 생각했습니다.
Mark Byers

1
"strlwr"을 사용하지 않는 이유는 무엇입니까? strlwr((char*)str);문자열을 통과하여 자체적으로 변환합니다.
Larry

@Larry 비표준입니다.
중순

답변:


152

그것은 표준 라이브러리에 있으며, 이러한 기능을 구현하는 가장 직접적인 방법입니다. 예, 문자열을 반복하고 각 문자를 소문자로 변환하십시오.

다음과 같은 사소한 것 :

#include <ctype.h>

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

또는 하나의 라이너를 선호하는 경우 JF Sebastian에서 다음을 사용할 수 있습니다.

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

35
for ( ; *p; ++p) *p = tolower(*p);더 관용적으로 보입니다.
jfs 2010-04-18

14
@JF 거기 당신이 간다. 코드가 무섭거나 멋지게 보이길 원하는지에 따라 다릅니다. :) (아주 읽기 쉬운 하나의 라이너이지만 무섭게 보입니다)
Earlz

이것은 str이 a이면 segfault를 제공 char *하지만 str이 char 배열이면 아닙니다. 그것에 대한 설명이 있습니까?
Electric Coffee

1
나는 하나의 라이너가 당신이 문자열에 대한 포인터를 잃게 할 것이라고 믿습니다.
Ace.C

2
나는 하나의 라이너가 엄청난 결과를 가져올 것이라고 믿습니다.
NOP da CALL

7

소문자로 변환하는 것은 ASCII로 제한하는 경우 상승 비트 0x60과 같습니다.

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

6
좀 더 읽기 쉽게 만들려면 할 수 있습니다for(char *p = pstr;*p;++p) *p=*p>='A'&&*p<='Z'?*p|0x60:*p;
Grant Peters

7
이 버전은 실제로 glibc의 tolower(). 내 컴퓨터에서 55.2 대 44.15.
jfs

나는 그것을 상상할 수 없다 : 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 문자열 만 다루고 있으며 로케일 문제가 없습니까? 그렇다면 네, 그렇게하는 것이 좋은 방법이 될 것입니다.


tolower ()가 non-ascii az char에서 호출되면 어떻게됩니까? 처럼 '!' 또는 '#'. 나는 그것을 '#'에서 테스트했고 괜찮은 것 같았다. 이것은 일반적으로 문자 az가 아닌 모든 ASCII 문자에 해당합니까?
Tony Stark

1
@hatorade : tolower()'A'.. 'Z'범위에 있지 않으면 인수를 변경하지 않고 그대로 둡니다.
jfs

1
! 및 #은 모두 ASCII 문자입니다. 마크는 문자 당 1 바이트 (이 솔루션처럼)가 있다고 가정 할 수 UTF8, 같은 다른 인코딩을 언급했다
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.