Saya mencoba mendapatkan program untuk membiarkan pengguna memasukkan kata atau karakter, menyimpannya, dan mencetaknya hingga pengguna mengetiknya lagi, keluar dari program. Kode saya terlihat seperti ini:
#include <stdio.h>
int main()
{
char input[40];
char check[40];
int i=0;
printf("Hello!\nPlease enter a word or character:\n");
gets(input);
printf("I will now repeat this until you type it back to me.\n");
while (check != input)
{
printf("%s\n", input);
gets(check);
}
printf("Good bye!");
return 0;
}
Masalahnya adalah bahwa saya terus mendapatkan pencetakan dari string input, bahkan ketika input oleh pengguna (centang) cocok dengan yang asli (input). Apakah saya salah membandingkan keduanya?
gets( )
telah dihapus dari standar. Gunakanfgets( )
sebagai gantinya.strcmp()
mengembalikan nol ketika inputnya sama menjelaskan bagaimana membandingkan string untuk kesetaraan, ketidaksetaraan, kurang dari, lebih besar dari, lebih kecil dari atau sama, dan lebih besar dari atau sama. Tidak semua perbandingan string adalah untuk kesetaraan. Perbandingan case sensitif berbeda lagi; perbandingan khusus lainnya (urutan kamus, misalnya) memerlukan pembanding yang lebih khusus, dan ada regex untuk perbandingan yang lebih kompleks.gets()
adalah no-go. Itu juga telah dihapus dari standar sejak C11 -> Silakan baca Mengapa fungsi mendapat begitu berbahaya sehingga tidak boleh digunakan?Jawaban:
Anda tidak dapat (berguna) membandingkan string menggunakan
!=
atau==
, Anda perlu menggunakanstrcmp
:Alasan untuk ini adalah karena
!=
dan==
hanya akan membandingkan alamat basis dari string tersebut. Bukan isi dawai itu sendiri.sumber
while (strcmp(check, input))
sudah memadai dan dianggap praktik yang baik.Ok beberapa hal:
gets
tidak aman dan harus digantifgets(input, sizeof(input), stdin)
sehingga Anda tidak mendapatkan buffer overflow.Selanjutnya, untuk membandingkan string, Anda harus menggunakan
strcmp
, di mana nilai balik 0 menunjukkan bahwa kedua string cocok. Menggunakan operator kesetaraan (mis.!=
) Membandingkan alamat dari dua string, yang bertentangan dengan individuchar
di dalamnya.Dan juga perhatikan bahwa, sementara dalam contoh ini tidak akan menimbulkan masalah,
fgets
menyimpan karakter baris baru,'\n'
di buffer juga;gets()
tidak. Jika Anda membandingkan input pengguna darifgets()
string literal seperti"abc"
itu tidak akan pernah cocok (kecuali buffer terlalu kecil sehingga'\n'
tidak muat di dalamnya).sumber
fgets()
, maka string mungkin"abc\n"
karenafgets()
menjaga baris baru. Jika Anda membandingkannya dengan"abc"
, Anda akan mendapatkan 'tidak sama' karena perbedaan antara terminasi null byte"abc"
dan baris baru dalam data yang dibaca. Jadi, Anda harus zap baris baru. Cara satu garis yang dapat diandalkan untuk melakukan itu adalahbuffer[strcspn(buffer, "\n")] = '\0';
yang memiliki manfaat bekerja dengan benar terlepas dari apakah ada data dalam buffer, atau apakah data itu berakhir dengan baris baru atau tidak. Cara lain untuk mengubah saluran baru dengan mudah macet.Gunakan
strcmp
.Ini ada di
string.h
perpustakaan, dan sangat populer.strcmp
mengembalikan 0 jika string sama. Lihat ini untuk penjelasan yang lebih baik tentang apa yangstrcmp
kembali.Pada dasarnya, Anda harus melakukan:
atau
atau
Anda dapat memeriksa ini , tutorial tentang
strcmp
.sumber
Anda tidak dapat membandingkan array secara langsung seperti ini
Anda harus membandingkannya char-by-char; untuk ini, Anda dapat menggunakan fungsi dan mengembalikan nilai boolean (True: 1, False: 0). Kemudian Anda dapat menggunakannya dalam kondisi pengujian loop sementara.
Coba ini:
sumber
checker
ditemukan'\0'
di salah satu string, itu tidak memeriksa string yang lain'\0'
. Fungsi mengembalikan1
("sama") bahkan jika satu string hanya awalan dari yang lain (misalnya,"foo"
dan"foobar"
).||
sebagai gantinya&&
.Selamat datang di konsep penunjuk. Generasi pemrogram pemula telah menemukan konsep itu sulit dipahami, tetapi jika Anda ingin tumbuh menjadi programmer yang kompeten, Anda akhirnya harus menguasai konsep ini - dan terlebih lagi, Anda sudah mengajukan pertanyaan yang tepat. Itu bagus.
Apakah jelas bagi Anda alamat itu apa? Lihat diagram ini:
Dalam diagram, bilangan bulat 1 disimpan dalam memori di alamat 0x4000. Kenapa di alamat? Karena ingatannya besar dan dapat menyimpan banyak bilangan bulat, sama seperti sebuah kota besar dan dapat menampung banyak keluarga. Setiap bilangan bulat disimpan di lokasi memori, karena setiap keluarga berada di rumah. Setiap lokasi memori diidentifikasi oleh alamat , karena setiap rumah diidentifikasi oleh alamat.
Dua kotak dalam diagram mewakili dua lokasi memori yang berbeda. Anda dapat menganggap mereka seolah-olah mereka adalah rumah. Bilangan bulat 1 berada di lokasi memori di alamat 0x4000 (pikirkan, "4000 Elm St."). Bilangan bulat 7 berada di lokasi memori di alamat 0x4004 (pikirkan, "4004 Elm St.").
Anda mengira program Anda membandingkan angka 1 dengan angka 7, tetapi ternyata tidak. Itu membandingkan 0x4000 dengan 0x4004. Jadi apa yang terjadi ketika Anda memiliki situasi ini?
Kedua bilangan bulat itu sama tetapi alamatnya berbeda. Program Anda membandingkan alamat.
sumber
Setiap kali Anda mencoba membandingkan string, bandingkan dengan masing-masing karakter. Untuk ini, Anda dapat menggunakan fungsi string bawaan yang disebut strcmp (input1, input2); dan Anda harus menggunakan file header yang disebut
#include<string.h>
Coba kode ini:
sumber
Mari kita gali lebih dalam untuk melihat mengapa
check != input
tidak cukup .Dalam C, string adalah spesifikasi perpustakaan standar.
input
di atas bukan string .input
adalah array 40 dari char .Isi
input
bisa menjadi string .Dalam kebanyakan kasus, ketika sebuah array digunakan dalam ekspresi, itu dikonversi ke alamat elemen pertama.
Di bawah ini mengkonversi
check
daninput
ke masing-masing alamat elemen pertama, kemudian alamat tersebut dibandingkan.Untuk membandingkan string , kita perlu menggunakan alamat itu dan kemudian melihat data yang mereka tuju.
strcmp()
melakukan pekerjaan . §7.23.4.2Tidak hanya kode yang dapat menemukan apakah string memiliki data yang sama, tetapi mana yang lebih besar / kurang ketika mereka berbeda.
Di bawah ini benar ketika string berbeda.
Untuk wawasan, lihat Membuat
strcmp()
fungsi saya sendirisumber
Ini adalah solusi yang sangat sederhana di mana Anda akan mendapatkan output seperti yang Anda inginkan.
sumber
gets();
bukan bagian dari standar C sejak C11.strcmp(s1,s2)
adalah UB karenas2
isinya tidak ditentukan pada awalnya.