Come faccio a minuscolo una stringa in C?


108

Come posso convertire una stringa di maiuscole e minuscole in una stringa minuscola in C?


2
Hai a che fare con ASCII solo con lettere az?
Mark Byers

1
ascii. come lo terrei in considerazione? l'esempio qui sotto funzionerebbe ancora? cosa succede se il mio carattere è un '#' e viene chiamato tolower ()?
Tony Stark

1
Funzionerà. Stavo più pensando se la tua stringa contiene cose come é o Ü.
Mark Byers

1
Perché non usare semplicemente "strlwr"? strlwr((char*)str);Passa semplicemente attraverso la stringa e la converte.
Larry

1
@ Larry Non è standard.
metà

Risposte:


153

È nella libreria standard, e questo è il modo più diretto che posso vedere per implementare una tale funzione. Quindi sì, basta scorrere la stringa e convertire ogni carattere in minuscolo.

Qualcosa di banale come questo:

#include <ctype.h>

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

o se preferisci una riga, puoi usare questa di JF Sebastian:

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

35
for ( ; *p; ++p) *p = tolower(*p);sembra più idiomatico.
jfs

14
@JF eccoti. Dipende se vogliono che il codice
appaia

questo mi dà un segfault se str è a char *, ma non se str è un array di caratteri. Hai qualche spiegazione per questo?
Caffè elettrico

1
Credo che l'unico liner ti farà perdere il puntatore alla stringa.
Ace.C

2
Credo che una nave avrà ramificazioni indicibili.
NOP da CALL

7

convertire in minuscolo equivale a aumentare il bit 0x60 se ti limiti ad ASCII:

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

6
Per renderlo leggermente più leggibile potresti farefor(char *p = pstr;*p;++p) *p=*p>='A'&&*p<='Z'?*p|0x60:*p;
Grant Peters

7
Questa versione è in realtà più lenta di quella di glibc tolower(). 55.2 contro 44.15 sulla mia macchina.
jfs

Non riesco a immaginare che: tolower () si occupa di caratteri; solo se è macro
Oleg Razgulyaev

1
@oraz: tolower () ha la int (*)(int)firma. Ecco il codice utilizzato per le misurazioni delle prestazioni gist.github.com/370497
jfs

@JF: vedo, hanno usato la tabella, ma posso ottimizzare: for (; * p; ++ p) if (* p> 'Z') {continue;} else if (* p <'A') {continue;} else {* p = * p | 0x60;}
Oleg Razgulyaev

1

Hai solo a che fare con stringhe ASCII e non hai problemi di locale? Allora sì, sarebbe un buon modo per farlo.


cosa succede se tolower () viene chiamato su un carattere non ASCII az? piace '!' o '#'. l'ho provato su "#" e sembrava funzionare bene. è generalmente vero per tutti i caratteri ASCII che non sono lettere az?
Tony Stark

1
@hatorade: tolower()lascia l'argomento invariato se non si trova nell'intervallo "A" .. "Z".
jfs

1
! e # sono entrambi caratteri ascii. Mark si riferiva ad altre codifiche come UTF8, dove non puoi presumere che ci sia un byte per carattere (come fa questa soluzione)
hdgarrood


1

Se vogliamo essere così sciatti da usare tolower(), fallo:

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

Ma, beh, un po 'esplode se gli dai dei simboli / numeri, e in generale è malvagio. Buona domanda per l'intervista, però.


6
Sì, questo piegherà / manderà / mutilerà una varietà di simboli (in ASCII, qualsiasi simbolo, carattere di controllo o numero con bit 5 chiaro diventerà lo stesso codice carattere con il bit 5 impostato, ecc.) Quindi davvero, seriamente, non farlo usalo.
Ken S

Questo post è discusso su meta .
Patrick Hofman

0

Ripetere il puntatore per ottenere prestazioni migliori:

#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;
}
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.