Saya memiliki program berikut:
int main(int argc, char *argv[])
{
int a, b;
char c1, c2;
printf("Enter something: ");
scanf("%d",&a); // line 1
printf("Enter other something: ");
scanf("%d", &b); // line 2
printf("Enter a char: ");
scanf("%c",&c1); // line 3
printf("Enter another char: ");
scanf("%c", &c2); // line 4
printf("Done"); // line 5
system("PAUSE");
return 0;
}
Seperti yang saya baca di buku C, penulis mengatakan bahwa scanf()
meninggalkan karakter baris baru di buffer, oleh karena itu, program tidak berhenti di baris 4 bagi pengguna untuk memasukkan data, melainkan menyimpan karakter baris baru di c2 dan berpindah ke baris 5.
Apakah itu benar?
Namun, apakah ini hanya terjadi dengan char
tipe data? Karena saya tidak melihat masalah ini dengan int
tipe data seperti pada baris 1, 2, 3. Apakah benar?
fflush(stdin)
dapat digunakan sebelum panggilan kescanf()
untuk satu karakter. Harap baca Menggunakanfflush(stdin)
untuk diskusi tentang pro dan kontra serta alternatif metode tersebut (yang bekerja, kurang lebih, pada Windows, dan tidak berfungsi di sebagian besar tempat lain).Jawaban:
The
scanf()
melompat fungsi spasi terkemuka otomatis sebelum mencoba untuk mengurai konversi selain karakter. Format karakter (terutama%c
; juga set scan%[…]
- dan%n
) adalah pengecualian; mereka tidak melewatkan spasi.Gunakan
" %c"
dengan awalan kosong untuk melewati spasi kosong opsional. Jangan gunakan tanda kosong dalamscanf()
format string.Perhatikan bahwa ini masih tidak mengkonsumsi spasi kosong tertinggal di aliran input, bahkan tidak sampai akhir baris, jadi berhati-hatilah jika juga menggunakan
getchar()
ataufgets()
pada aliran input yang sama. Kami baru saja mendapatkan scanf untuk melewati spasi sebelum konversi, seperti yang dilakukannya untuk%d
dan konversi non-karakter lainnya.Perhatikan bahwa "perintah" non-spasi putih (untuk menggunakan terminologi scanf POSIX ) selain konversi, seperti teks literal dalam
scanf("order = %d", &order);
juga tidak melewatkan spasi. Literalorder
harus cocok dengan karakter berikutnya untuk dibaca.Jadi, Anda mungkin menginginkannya
" order = %d"
jika Anda ingin melewati baris baru dari baris sebelumnya tetapi masih membutuhkan pencocokan literal pada string tetap, seperti pertanyaan ini .sumber
%c
,%n
,%[]
Adalah 3 harapan tertentu yang tidak mengkonsumsi spasi terkemuka.scanf()
format string danscanf()
meminta input dua kali sementara saya mengharapkannya untuk meminta hanya sekali untuk diskusi tentang trailing blank dalam string format. Itu adalah ide yang buruk - sangat buruk jika Anda mengharapkan interaksi manusia dan buruk untuk interaksi program.Gunakan
scanf(" %c", &c2);
. Ini akan menyelesaikan masalah Anda.sumber
Opsi lain (yang saya dapatkan dari sini ) adalah membaca dan membuang baris baru dengan menggunakan opsi penugasan-supresi . Untuk melakukan itu, kami hanya menempatkan format untuk membaca karakter dengan tanda bintang di antara
%
danc
:scanf("%d%*c",&a); // line 1 scanf("%c%*c",&c1); // line 3
scanf
kemudian akan membaca karakter berikutnya (yaitu, baris baru) tetapi tidak menugaskannya ke penunjuk mana pun.Pada akhirnya, bagaimanapun, saya akan mendukung opsi terakhir FAQ :
sumber
a
spasi lalu baris baru, konversi karakter yang disembunyikan membaca spasi dan masih meninggalkan baris baru. Jika pengguna mengetik sesuaisupercalifragilisticexpialidocious
harapana
, Anda memiliki banyak karakter tambahan yang harus ditangani. Anda juga tidak akan pernah tahu apakah konversi tambahan yang ditutup-tutupi berhasil - konversi tidak dihitung sebagai imbalan dariscanf()
.Gunakan
getchar()
sebelum menelepon keduascanf()
.scanf("%c", &c1); getchar(); // <== remove newline scanf("%c", &c2);
sumber
int c; while ((c = getchar()) != EOF && c != '\n') ;
(ditulis lebih dari tiga baris jika tidak ada dalam komentar). Seringkali cukup; ini tidak mudah (dan Anda harus ingat bahwa orang bodoh sangat pandai dalam menghancurkan sesuatu).