Bottom-line top: Dengan penanganan ruang putih yang benar, berikut ini adalah bagaimana eof
dapat digunakan (dan bahkan, lebih dapat diandalkan daripada fail()
untuk pengecekan kesalahan):
while( !(in>>std::ws).eof() ) {
int data;
in >> data;
if ( in.fail() ) /* handle with break or throw */;
// now use data
}
( Terima kasih Tony D atas saran untuk menyoroti jawabannya. Lihat komentarnya di bawah ini untuk contoh mengapa ini lebih kuat. )
Argumen utama menentang penggunaan eof()
tampaknya tidak ada seluk beluk penting tentang peran ruang putih. Proposisi saya adalah bahwa, memeriksa eof()
secara eksplisit tidak hanya bukan " selalu salah " - yang tampaknya menjadi pendapat utama dalam hal ini dan utas SO yang serupa -, tetapi dengan penanganan ruang putih yang tepat, ini memberikan pembersih dan lebih dapat diandalkan penanganan kesalahan, dan merupakan solusi yang selalu benar (walaupun, belum tentu yang tersest).
Untuk meringkas apa yang disarankan sebagai penghentian dan baca "benar" adalah sebagai berikut:
int data;
while(in >> data) { /* ... */ }
// which is equivalent to
while( !(in >> data).fail() ) { /* ... */ }
Kegagalan karena upaya membaca di luar bukti diambil sebagai kondisi penghentian. Ini berarti bahwa tidak ada cara mudah untuk membedakan antara aliran yang berhasil dan yang benar-benar gagal karena alasan selain eof. Ambil aliran berikut:
1 2 3 4 5<eof>
1 2 a 3 4 5<eof>
a<eof>
while(in>>data)
berakhir dengan satu set failbit
untuk semua tiga masukan. Di bagian pertama dan ketiga, eofbit
juga diatur. Jadi melewati loop kita perlu logika ekstra yang sangat buruk untuk membedakan input yang tepat (1) dari yang tidak tepat (2 dan 3).
Sedangkan, ambil yang berikut:
while( !in.eof() )
{
int data;
in >> data;
if ( in.fail() ) /* handle with break or throw */;
// now use data
}
Di sini, in.fail()
memverifikasi bahwa selama ada sesuatu untuk dibaca, itu adalah yang benar. Tujuannya bukanlah terminator loop sementara.
Sejauh ini bagus, tapi apa yang terjadi jika ada ruang tambahan di sungai - apa yang terdengar seperti kekhawatiran utama eof()
sebagai terminator?
Kami tidak perlu menyerahkan penanganan kesalahan kami; cukup makan ruang putih:
while( !in.eof() )
{
int data;
in >> data >> ws; // eat whitespace with std::ws
if ( in.fail() ) /* handle with break or throw */;
// now use data
}
std::ws
melompati potensi (nol atau lebih) spasi tambahan di aliran saat mengatur eofbit
, dan bukanfailbit
. Jadi, in.fail()
berfungsi seperti yang diharapkan, selama setidaknya ada satu data untuk dibaca. Jika aliran semua-kosong juga dapat diterima, maka formulir yang benar adalah:
while( !(in>>ws).eof() )
{
int data;
in >> data;
if ( in.fail() ) /* handle with break or throw */;
/* this will never fire if the eof is reached cleanly */
// now use data
}
Ringkasan: Dibuat dengan benar while(!eof)
tidak hanya mungkin dan tidak salah, tetapi memungkinkan data untuk dilokalisasi dalam ruang lingkup, dan menyediakan pemisahan yang lebih bersih dari pengecekan kesalahan dari bisnis seperti biasa. Yang sedang berkata, while(!fail)
mungkin idiom yang lebih umum dan singkat, dan mungkin lebih disukai dalam skenario sederhana (data tunggal per jenis baca).
scanf(...) != EOF
juga tidak akan berfungsi di C, karenascanf
mengembalikan jumlah bidang yang berhasil diuraikan dan ditugaskan. Kondisi yang benar adalah discanf(...) < n
manan
jumlah bidang dalam string format.