私はユーザー入力から直接データを読み取るプログラムをコーディングしていて、標準入力からEOFまですべてのデータを(ループなしで)どのように読み取ることができるのか疑問に思っていました。私は使用を検討してcin.get( input, '\0' )
いました'\0'
が、実際にはEOF文字ではなく、EOFまたは'\0'
のいずれか早い方まで読み取るだけです。
それとも、ループを使用することがそれを行う唯一の方法ですか?もしそうなら、最善の方法は何ですか?
可変量のデータを読み取る唯一の方法stdin
は、ループを使用することです。私はいつも、std::getline()
関数が非常にうまく機能することを発見しました:
std::string line;
while (std::getline(std::cin, line))
{
std::cout << line << std::endl;
}
デフォルトでgetline()
は、改行まで読み取ります。別の終了文字を指定できますが、EOF 自体は文字ではないため、単純に を 1 回呼び出すことはできませんgetline()
。
ループの使用:
#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))
{
...
}
ストリーム反復子を使用すると、明示的なループなしで実行できます。内部である種のループを使用していると確信しています。
#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;
}
を使用して KeithB のソリューションを調査した後std::istream_iterator
、 を発見しましたstd:istreambuf_iterator
。
パイプされたすべての入力を文字列に読み取り、再度書き出すプログラムをテストします。
#include <iostream>
#include <iterator>
#include <string>
int main()
{
std::istreambuf_iterator<char> begin(std::cin), end;
std::string s(begin, end);
std::cout << s;
}
std::istream::getline() (またはできれば std::string で動作するバージョン)関数を使用して、行全体を取得できます。両方とも、区切り文字 (行末文字) を指定できるバージョンがあります。文字列バージョンのデフォルトは '\n' です。
while(std::cin) {
// do something
}
待って、私はあなたを正しく理解していますか?キーボード入力に cin を使用していて、ユーザーが EOF 文字を入力したときに入力の読み取りを停止したいですか? ユーザーが EOF 文字を入力するのはなぜでしょうか? それとも、EOF でファイルからの読み取りを停止したいということですか?
実際に cin を使用して EOF 文字を読み取ろうとしている場合は、EOF を区切り文字として指定しないのはなぜですか?
// Needed headers: iostream
char buffer[256];
cin.get( buffer, '\x1A' );
EOF でファイルからの読み取りを停止する場合は、getline を使用して、もう一度 EOF を区切り文字として指定します。
// Needed headers: iostream, string, and fstream
string buffer;
ifstream fin;
fin.open("test.txt");
if(fin.is_open()) {
getline(fin,buffer,'\x1A');
fin.close();
}
1つのオプションは、コンテナを使用することです。
std::vector<char> data;
が受信されるまで、すべての入力をこのコレクションにリダイレクトします。EOF
std::copy(std::istream_iterator<char>(std::cin),
std::istream_iterator<char>(),
std::back_inserter(data));
ただし、使用されているコンテナーは頻繁にメモリを再割り当てする必要がある場合があります。そうstd::bad_alloc
しないと、システムがメモリ不足になったときに例外が発生して終了します。これらの問題を解決するために、一定量の要素を確保し、これらの要素を分離して処理することができます。つまり、N
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();
}