Bagaimana cara menurunkan huruf kecil di C?


108

Bagaimana cara mengubah string kasus campuran menjadi string huruf kecil di C?


2
Apakah Anda hanya berurusan dengan ASCII dengan huruf az saja?
Mark Byers

1
ascii. bagaimana saya memperhitungkannya? apakah contoh di bawah ini akan tetap berfungsi? apa yang terjadi jika karakter saya adalah '#' dan tolower () dipanggil?
Tony Stark

1
Itu akan bekerja. Saya lebih berpikir jika string Anda berisi hal-hal seperti é atau Ü.
Mark Byers

1
Mengapa tidak menggunakan "strlwr" saja? strlwr((char*)str);Itu hanya melewati string dan mengubahnya sendiri.
Larry

1
@ Larry Ini non-standar.
Pertengahan

Jawaban:


153

Ada di pustaka standar, dan itulah cara paling mudah yang dapat saya lihat untuk mengimplementasikan fungsi seperti itu. Jadi ya, cukup putar melalui string dan ubah setiap karakter menjadi huruf kecil.

Sesuatu yang sepele seperti ini:

#include <ctype.h>

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

atau jika Anda lebih suka satu liner, maka Anda dapat menggunakan yang ini dari JF Sebastian:

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

35
for ( ; *p; ++p) *p = tolower(*p);tampaknya lebih idiomatis.
jfs

14
@JF itu dia. Tergantung pada apakah mereka ingin kodenya terlihat menakutkan atau bagus :) (satu baris yang sangat mudah dibaca, tetapi memang terlihat menakutkan)
Earlz

ini memberi saya segfault jika str adalah a char *, tetapi tidak jika str adalah array char. Punya penjelasan untuk itu?
Kopi Elektrik

1
Saya percaya satu liner akan menyebabkan Anda kehilangan pointer Anda ke string.
Ace.C

2
Saya percaya bahwa satu liner akan memiliki konsekuensi yang tak terhitung.
NOP da CALL

7

untuk mengonversi ke huruf kecil sama dengan bit naik 0x60 jika Anda membatasi diri Anda pada ASCII:

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

6
Untuk membuatnya sedikit lebih mudah dibaca, Anda dapat melakukannyafor(char *p = pstr;*p;++p) *p=*p>='A'&&*p<='Z'?*p|0x60:*p;
Grant Peters

7
Versi ini sebenarnya lebih lambat dari versi glibc tolower(). 55.2 vs. 44.15 di komputer saya.
jfs

saya tidak bisa membayangkan bahwa: tolower () berurusan dengan karakter; hanya jika itu makro
Oleg Razgulyaev

1
@oraz: tolower () memiliki int (*)(int)tanda tangan. Berikut kode yang digunakan untuk pengukuran kinerja gist.github.com/370497
jfs

@JF: begitu, mereka telah menggunakan tabel, tetapi saya dapat mengoptimalkan: for (; * p; ++ p) if (* p> 'Z') {lanjutkan;} else if (* p <'A') {lanjutkan;} lain {* p = * p | 0x60;}
Oleg Razgulyaev

1

Apakah Anda hanya berurusan dengan string ASCII, dan tidak memiliki masalah lokal? Kalau begitu ya, itu cara yang bagus untuk melakukannya.


apa yang terjadi jika tolower () dipanggil pada non-ascii az char? Suka '!' atau '#'. saya mengujinya di '#' dan tampaknya berfungsi dengan baik. apakah ini umumnya benar untuk semua karakter ascii yang bukan huruf az?
Tony Stark

1
@hatorade: tolower()membiarkan argumen tidak berubah jika tidak ada dalam kisaran 'A' .. 'Z'.
jfs

1
! dan # keduanya karakter ascii. Mark mengacu pada pengkodean lain seperti UTF8, di mana Anda tidak dapat berasumsi bahwa ada satu byte per karakter (seperti yang dilakukan solusi ini)
hdgarrood


1

Jika kita akan menjadi ceroboh dalam menggunakan tolower(), lakukan ini:

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

Tapi, yah, itu agak meledak jika Anda memberinya beberapa simbol / angka, dan secara umum itu jahat. Pertanyaan wawancara yang bagus.


6
Ya, ini akan melipat / spindle / memutilasi berbagai simbol (di ASCII, simbol apa pun, karakter kontrol, atau angka dengan bit 5 jelas akan menjadi kode karakter yang sama dengan set bit 5, dll) jadi sungguh, serius, jangan Gunakan.
Ken S

Posting ini dibahas di meta .
Patrick Hofman

0

Memutar ulang penunjuk untuk mendapatkan kinerja yang lebih baik:

#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;
}
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.