2009-12-16 5 views
4

저는 Microsoft Visual C++로 작성 중이며 istream_iterator을 사용하여 프로그램을 표준 입력 또는 파일에서 읽으려고합니다. 인터네트를 인터넷으로 검색하는 것은 그것이 얼마나 단순해야한다고 생각하는지 보여주지 못했습니다. 그래서 예를 들어, 나는 매우 쉽게 쓸 수 및 표준 입력으로부터 읽어istream_iterator를 사용하여 표준 입력 또는 파일에서 읽기

#include <iostream> 
#include <string> 
#include <iterator> 

using namespace std; 

int main() 
{ 
    istream_iterator<string> my_it(cin); 
    for (; my_it != istream_iterator<string>(); my_it++) 
     printf("%s\n", (*my_it).c_str()); 
} 

아니면이를 작성하고 파일에서 읽을 수 있습니다

#include <iostream> 
#include <string> 
#include <iterator> 
#include <fstream> 

using namespace std; 

int main(int argc, char** argv) 
{ 
    ifstream file(argv[1]); 
    istream_iterator<string> my_it(file); 
    for (; my_it != istream_iterator<string>(); my_it++) 
     printf("%s\n", (*my_it).c_str()); 
} 

하지만 어떻게 내가 그래서이 두 가지를 결합 할 간단한 (argc == 2) 체크를 사용하면 파일 스트림이나 stdin으로 입력 스트림 반복자를 초기화하고 내 기쁜 방법으로 진행할 수 있습니까?

답변

10

당신은 그것을 구성 후 반복자에 할당 할 수 있습니다

int main(int argc, char** argv) 
{ 
    ifstream file; 
    istream_iterator<string> my_it; 

    if(argc == 2) { 
     file.open(argv[1]); 
     my_it = istream_iterator<string>(file); 
    } else { 
     my_it = istream_iterator<string>(cin); 
    } 
} 
1

작은 스 니펫은 파일 또는 std :: cin이 될 수있는 istream input을 제공합니다.

std::ifstream filestream; 
if (use_file) 
    filestream.open(...); 
std::istream &input = use_file ? filestream : std::cin; 

input은 입력 소스가 걱정되지 않아도 사용할 수 있습니다.

+0

이것은 r 값을 비 const 참조에 바인드하려고 시도하며 C++에서는 유효하지 않습니다. –

+0

@Alex : 하나의 피연산자가 다른 유형의 참조로 암시 적으로 변환 될 수있는 경우 결과는 왼쪽 값입니다. http://www.open-std.org/jtc1/sc22/wg21/docs/wp/html/nov97-2/expr.html#expr.cond –

+0

올바른 것으로 보입니다 - VC 2008에서는 문제없이 컴파일합니다. . VC 2005 버그와 같습니다. –

0

당신은 같은 것을 의미합니까 : (포인터를 사용) 그래도,이 테스트를하지 않은

#include <iostream> 
#include <string> 
#include <iterator> 
#include <fstream> 

using namespace std; 

int main(int argc, char** argv) 
{ 
    istream_iterator<string>* my_it = NULL; 
    if (argc == 2) 
    { 
     ifstream file(argv[1]); 
     my_it = new istream_iterator<string>(file); 
    } 
    else 
    { 
     my_it = new istream_iterator<string>(cin); 
    } 

    ... 

    delete my_it; 
} 

. 그게 당신이 쫓아 온거야?

1

을 언뜻보기에 간단한 해결책은 다음과 같이 삼항 연산자 ?:을 사용하는 것입니다 : 그러나

istream_iterator<string> my_it((argc == 2) ? ifstream(argv[1]) : cin); 

, 그 원 명령문의 끝에서 파괴 될 임시 ifstream 오브젝트를 생성하기 때문에 꽤 효과적이지 않습니다. 따라서 ifstream을 조건부로 생성하고 for 루프 이후에 조건부로 파기하는 방법이 필요합니다. std::auto_ptr<>이 청구서에 들어갑니다. 따라서 :

auto_ptr<ifstream> file((argc == 2) ? new ifstream(argv[1]) : NULL); 
istream_iterator<string> my_it((argc == 2) : *file : cin); 
for (; my_it != istream_iterator<string>(); my_it++) 
    printf("%s\n", (*my_it).c_str()); 

다른, 아마 청소기 솔루션 istream& 소요 별도의 함수에 반복을 이동하는 것입니다.

온라인에서이 문제를 보았습니다.이 문제는 C++ 위대한 사람들이 다루었습니다. 불행히도, 나는 정확히 어디서, 또는 누구에 의해 기억이 나지 않습니다! DDJ에 있었던 것 같아요, 어쩌면 셔터 나 Alexandrescu일까요?

+0

이것은 또한 rvalue를 비 const 참조에 바인드하려고 시도합니다. VC++ :'비 const 레퍼런스는 좌변에만 붙을 수 있습니다' –