Saya coding program yang membaca data langsung dari input pengguna dan bertanya-tanya bagaimana aku bisa (tanpa loop) membaca semua data sampai EOF dari standar input. Saya sedang mempertimbangkan untuk menggunakan cin.mendapatkan( input, '\0' )
tapi'\0'
tidak benar-benar EOF karakter, yang hanya membaca sampai EOF atau'\0'
, mana yang lebih dulu.
Atau menggunakan loop satu-satunya cara untuk melakukannya? Jika demikian, apa cara yang terbaik?
Satu-satunya cara anda dapat membaca variabel jumlah data dari stdin adalah dengan menggunakan loop. I've selalu menemukan bahwa std::getline()
fungsi bekerja dengan sangat baik:
std::string line;
while (std::getline(std::cin, line))
{
std::cout << line << std::endl;
}
Secara default getline() membaca sampai baris baru. Anda dapat menentukan alternatif penghentian karakter, tapi EOF tidak sendiri karakter sehingga anda tidak bisa hanya membuat satu panggilan untuk getline().
Anda dapat melakukannya tanpa eksplisit loop dengan menggunakan aliran iterator. I'm yakin bahwa ia menggunakan semacam lingkaran internal.
#include <string>
#include <iostream>
#include <istream>
#include <ostream>
#include <iterator>
int main()
{
// don't skip the whitespace while reading
std::cin >> std::noskipws;
// use stream iterators to copy the stream to a string
std::istream_iterator<char> it(std::cin);
std::istream_iterator<char> end;
std::string results(it, end);
std::cout << results;
}
Menggunakan loop:
#include <iostream>
using namespace std;
...
// numbers
int n;
while (cin >> n)
{
...
}
// lines
string line;
while (getline(cin, line))
{
...
}
// characters
char c;
while (cin.get(c))
{
...
}
Setelah meneliti KeithB's solusi menggunakan std::istream_iterator
, saya menemukan std:istreambuf_iterator
.
Menguji program untuk membaca semua pipa masukan ke dalam string, maka menulis itu lagi:
#include <iostream>
#include <iterator>
#include <string>
int main()
{
std::istreambuf_iterator<char> begin(std::cin), end;
std::string s(begin, end);
std::cout << s;
}
Mungkin yang paling sederhana dan umumnya efisien:
#include <iostream>
int main()
{
std::cout << std::cin.rdbuf();
}
Jika diperlukan, gunakan aliran jenis lain seperti std::ostringstream
sebagai penyangga sebagai pengganti standard output stream di sini.
Sedih side note: saya memutuskan untuk menggunakan C++ IO untuk konsisten dengan boost berdasarkan kode. Dari jawaban untuk pertanyaan ini saya memilih sementara (std::getline(std::cin, line))
. Menggunakan g++ versi 4.5.3 (-O3) di cygwin (mintty) aku punya 2 MB/s throughput. Microsoft Visual C++ 2010 (/O2) membuatnya 40 MB/s untuk kode yang sama.
Setelah menulis ulang IO murni C sementara (fgets(buf, 100, stdin))
throughput melonjak hingga 90 MB/s di kedua diuji compiler. Yang membuat perbedaan untuk setiap input yang lebih besar dari 10 MB...
Anda dapat menggunakan std::istream::getline() (atau sebaiknya versi yang bekerja pada std::string) fungsi untuk mendapatkan seluruh lini. Keduanya memiliki versi yang memungkinkan anda untuk menentukan pembatas (end of line karakter). Default untuk string version adalah '\n'.
Salah satu pilihan adalah dengan menggunakan wadah, misalnya
std::vector<char> data;
dan mengarahkan semua input ke dalam koleksi ini sampai EOF
diterima, yaitu
std::copy(std::istream_iterator<char>(std::cin),
std::istream_iterator<char>(),
std::back_inserter(data));
Namun, wadah yang digunakan mungkin perlu untuk mengalokasikan memori yang terlalu sering, atau anda akan berakhir dengan sebuah std::bad_alloc
pengecualian ketika sistem anda akan keluar dari memori. Dalam rangka untuk memecahkan masalah ini, anda bisa cadangan jumlah yang tetap N
dari elemen-elemen dan proses ini jumlah elemen dalam isolasi, yaitu
data.reserve(N);
while (/*some condition is met*/)
{
std::copy_n(std::istream_iterator<char>(std::cin),
N,
std::back_inserter(data));
/* process data */
data.clear();
}
Tunggu, saya memahami anda dengan benar? Anda're menggunakan cin untuk input keyboard, dan anda ingin berhenti membaca input ketika pengguna memasuki EOF karakter? Mengapa pengguna pernah ketik di EOF karakter? Atau apakah anda berarti anda ingin berhenti membaca dari sebuah file di EOF?
Jika anda're-benar mencoba untuk menggunakan cin untuk membaca sebuah EOF karakter, maka mengapa tidak hanya menentukan EOF sebagai pembatas?
// Needed headers: iostream
char buffer[256];
cin.get( buffer, '\x1A' );
Jika anda bermaksud untuk berhenti membaca dari sebuah file di EOF, maka hanya menggunakan getline dan sekali lagi menentukan EOF sebagai pembatas.
// Needed headers: iostream, string, and fstream
string buffer;
ifstream fin;
fin.open("test.txt");
if(fin.is_open()) {
getline(fin,buffer,'\x1A');
fin.close();
}