Program Tip

C ++에서 cin에서 EOF까지 읽는 방법

programtip 2020. 10. 28. 20:32
반응형

C ++에서 cin에서 EOF까지 읽는 방법


사용자 입력에서 직접 데이터를 읽는 프로그램을 코딩하고 있으며 표준 입력에서 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 자체는 문자가 아니므로 getline ()을 한 번만 호출 할 수는 없습니다.


스트림 반복기를 사용하여 명시 적 루프없이이를 수행 할 수 있습니다. 내부적으로 일종의 루프를 사용한다고 확신합니다.

#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;
}

루프 사용 :

#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))
{
   ...
}

자원


사용 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;
}

가장 간단하고 일반적으로 효율적일 수 있습니다.

#include <iostream>
int main()
{
    std::cout << std::cin.rdbuf();
}

필요한 경우 std::ostringstream여기에서 표준 출력 스트림 대신 버퍼 와 같은 다른 유형의 스트림을 사용 하십시오.


당신이 사용할 수있는 표준 : : IStream을 ::의 getline () (또는 바람직하게는 표준 : : 문자열에 작품이 버전 ) 기능은 전체 라인을 얻을 수 있습니다. 둘 다 구분 기호 (줄 끝 문자)를 지정할 수있는 버전이 있습니다. 문자열 버전의 기본값은 '\ n'입니다.


Sad side note: I decided to use C++ IO to be consistent with boost based code. From answers to this question I chose while (std::getline(std::cin, line)). Using g++ version 4.5.3 (-O3) in cygwin (mintty) i got 2 MB/s throughput. Microsoft Visual C++ 2010 (/O2) made it 40 MB/s for the same code.

After rewriting the IO to pure C while (fgets(buf, 100, stdin)) the throughput jumped to 90 MB/s in both tested compilers. That makes a difference for any input bigger than 10 MB...


while(std::cin) {
 // do something
}

Wait, am I understanding you correctly? You're using cin for keyboard input, and you want to stop reading input when the user enters the EOF character? Why would the user ever type in the EOF character? Or did you mean you want to stop reading from a file at the EOF?

If you're actually trying to use cin to read an EOF character, then why not just specify the EOF as the delimiter?

// Needed headers: iostream

char buffer[256];
cin.get( buffer, '\x1A' );

If you mean to stop reading from a file at the EOF, then just use getline and once again specify the EOF as the delimiter.

// Needed headers: iostream, string, and fstream

string buffer;

    ifstream fin;
    fin.open("test.txt");
    if(fin.is_open()) {
        getline(fin,buffer,'\x1A');

        fin.close();
    }

One option is to a use a container, e.g.

std::vector<char> data;

and redirect all input into this collection until EOF is received, i.e.

std::copy(std::istream_iterator<char>(std::cin),
    std::istream_iterator<char>(),
    std::back_inserter(data));

However, the used container might need to reallocate memory too often, or you will end with a std::bad_alloc exception when your system gets out of memory. In order to solve these problems, you could reserve a fixed amount N of elements and process these amount of elements in isolation, i.e.

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();
}

참고URL : https://stackoverflow.com/questions/201992/how-to-read-until-eof-from-cin-in-c

반응형