C++ cin.get(), cin.peek() jeda, sama dengan stdio

Ini adalah kode saya seperti saat ini. Kode ini memunculkan kesalahan pada cin.get(). Saya mengerti ini bukan kode yang bagus, tidak seharusnya demikian, saya hanya menguji beberapa hal cin.

#include <string>
#include <iostream>
#include <stdio.h>

using namespace std;

int main(){
    char c[1000];
    cin.setstate(cin.eofbit);
    cout << cin.good() << endl;
    cout << cin.eof() <<endl;
    cout << cin.get() << endl;
    cin.putback('c');
    cout << cin.get() << endl;
    cout << "Do we ever reach this?" << endl;
    while(1){
    };
    return 0;
}

Bagaimanapun. Masalah saya adalah cin.get(), cin.peek(), cin.ignore(), getchar(), atau hampir semua fungsi cin atau stdio yang dapat Anda beri nama menjeda eksekusi program saya saat aliran kosong, tanpa pengaturan Bit EOF atau apa pun. Ini menjengkelkan bagi saya, karena saya ingin memeriksa apakah ada sesuatu di aliran sehingga saya dapat menghapusnya, karena abaikan() selalu dijeda.

Satu-satunya metode yang dapat saya gunakan adalah 'istream::readsome'. Saya telah memuat ini ke dalam array char dan mencetaknya menggunakan cout. Ini mencetak serangkaian simbol panjang yang tidak saya kenali (Masing-masing adalah simbol individual).

http://gyazo.com/e3ee65cdad7ed5cc7b2ce2307ca58c90

Ditransmisikan ke bilangan bulat, hasilnya adalah -52, yang tidak sama dengan apa pun di ASCII atau Unicode.

Saya mengkompilasi menggunakan Visual C++ Express 2010.

Tolong bantu, saya benar-benar bingung saat ini. Saya hanya ingin membaca karakter/membilas aliran saya, tanpa berhenti jika tidak ada apa-apa. Saya telah menghabiskan 3 jam untuk mencoba menyelesaikan ini. Mendesah.


person user1819357    schedule 12.11.2012    source sumber
comment
sync() membuang apa pun yang tersisa di buffer, namun perilaku tersebut tidak dijamin.   -  person chris    schedule 13.11.2012
comment
Terima kasih, saya akan melihatnya. Tapi apakah ada cara yang dijamin, atau cara untuk mencegah jeda yang mengerikan jika saya MELAKUKAN cin.ignore atau cin.peek?   -  person user1819357    schedule 13.11.2012
comment
OTOH, dengan memeriksa dengan benar hasil operasi I/O Anda, Anda tidak akan pernah sampai pada titik di mana Anda tidak tahu apakah alirannya kosong atau tidak.   -  person jrok    schedule 13.11.2012
comment
Namun saya tidak yakin bagaimana cara memeriksa dengan benar jika saya tidak dapat memeriksa apa yang tersisa di aliran tanpa secara tidak sengaja menjeda program saya. Plus, itu masih harus mengatur bit EOF bukan? Itu tidak diatur.   -  person user1819357    schedule 13.11.2012
comment
Untuk menyetel bit EOF dari konsol, ketik Ctrl + Z.   -  person Jesse Good    schedule 13.11.2012
comment
Bukan itu maksudku, Jesse. Saat saya mencoba mengekstrak karakter dari aliran kosong, alih-alih menyetel bit EOF (Seperti yang dikatakan di cplusplus.com), karakter tersebut menunggu masukan. Bahkan ketika saya hanya mengintip karakter selanjutnya.   -  person user1819357    schedule 13.11.2012
comment
@ user1819357: Benar, itulah yang seharusnya dilakukan (saya tidak tahu apa yang dikatakan cplusplus.com). Saya tidak mengerti mengapa std::getline dan std::string tidak cukup.   -  person Jesse Good    schedule 13.11.2012
comment
Sepertinya memang harus begitu, saya hanya ingin fleksibilitas ekstra diberikan dengan mencoba membaca streaming tanpa menyita keseluruhan program. Saya juga hanya mencoba memahami mengapa hal itu tampaknya berperilaku buruk. Mungkinkah ini masalah kompiler?   -  person user1819357    schedule 13.11.2012


Jawaban (1)


Untuk menghilangkan semua karakter yang diketahui tersedia, Anda dapat menggunakan std::istream::ignore() dikombinasikan dengan std::streambuf::in_avail():

std::cin.ignore(std::cin.rdbuf()->in_avail());

Namun, saya rasa ini tidak sesuai dengan keinginan Anda: Objek aliran standar hanya membaca apa pun yang diberikan sistem operasi. Biasanya, mode default untuk input yang terhubung ke semacam jendela konsol adalah dengan melakukan buffering baris pada input. Berapa banyak karakter yang benar-benar diserahkan ke aliran ini masih belum diketahui.

Untuk memeriksa apakah ada masukan yang tersedia pada aliran masukan, Anda perlu menggunakan metode khusus platform. Pustaka C++ standar tidak menyediakan pemeriksaan non-pemblokiran untuk melihat apakah data baru tiba di std::cin. Pada sistem POSIX Anda cukup menggunakan poll() dengan deskriptor file 0 untuk melihat apakah std::cin memiliki data. Apa yang dibutuhkan pada sistem non-POSIX saya tidak tahu.

person Dietmar Kühl    schedule 12.11.2012
comment
Aku sempat bermain-main dengan ini. IN_avail selalu mengembalikan 1, terlepas dari berapa banyak karakter yang saya masukkan kembali ke cin. Itu. Satu-satunya cara untuk menghapusnya lebih lanjut adalah dengan sinkronisasi(). Ditambah lagi abaikan memutuskan untuk menghentikan sementara, huh. Terima kasih atas tanggapannya, saya akan terus mencari sesuatu yang bisa memeriksanya di windows - person user1819357; 13.11.2012
comment
@ user1819357 apakah Anda menemukan cara untuk memeriksa Windows? - person Thomas Ibbotson; 05.08.2019